package com.youhome.report.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.youhome.common.enums.ZillowTypeEnum;
import com.youhome.common.exception.CustomException;
import com.youhome.service.listhub.*;
import com.youhome.service.model.*;
import com.youhome.service.response.*;
import com.youhome.service.result.SchoolItem;
import com.youhome.service.service.*;
import com.youhome.service.utils.*;
import com.youhome.utils.DateUtils;
import com.youhome.utils.DoubleUtils;
import net.sf.json.JSONException;
import org.jfree.data.category.DefaultCategoryDataset;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * Created by chen365 on 2018/08/14.
 */
@Controller
@RequestMapping(value = "/report")
public class ReportController {

    List<String> keys = new ArrayList<>();
    List<String> geometries_keys = new ArrayList<>();
    //是否查询相邻邮编数据
    @Value("${zillow.isSearchAdjacentZip}")
    private Boolean isSearchAdjacentZip;
    @Autowired
    private ChartService chartService;
    @Autowired
    private ListHubPhotoService listHubPhotoService;
    @Autowired
    private DownloadService downloadService;
    @Autowired
    private ListHubService listHubService;
    @Autowired
    private ZillowService zillowService;
    @Autowired
    private TruliaDataService truliaDataService;
    @Autowired
    private HomeJunctionService homeJunctionService;
    @Autowired
    private CityDataService cityDataService;
    @Autowired
    private HJZipCodeService hjZipCodeService;
    @Autowired
    private TranslateService translateService;
    @Autowired
    private ZipService zipService;
    @Value("classpath:static/json/details_values_translation.json")
    private Resource translationResource;
    @Value("classpath:static/json/details_values_translation_en.json")
    private Resource translationResourceEn;
    @Autowired
    private SolrService solrService;
    @Autowired
    private HJSchoolAttendanceAreaService hjSchoolAttendanceAreaService;
    @Autowired
    private TranslationService translationService;
    @Autowired
    private ZilLowByCityService zilLowByCityService;


    @Autowired
    private ReportZilLowService reportZilLowService;
    @Autowired
    private ZipCodeService zipCodeService;

    @GetMapping(value = "/free/{id}")
    public String free(Model model, @PathVariable String id, String template, Integer count,String regionType) {
        try {
            long startTime = System.currentTimeMillis();
            ListHub listHub = listHubService.selectByPrimaryKey(id);

            String zip = listHub.getZip(); // 邮编
            String state = listHub.getProvince(); //州
            String city = listHub.getCity(); // 市
            String county = listHub.getCounty(); //郡县

            TruliaDataWithBLOBs truliaDataWithBLOBs = null;
            if (!StringUtils.isEmpty(zip)) {
                truliaDataWithBLOBs = truliaDataService.selectByZipcode(zip);
            }
            //List<TimeSeriesDataAllHomes> timeSeriesDataAllHomesList = timeSeriesDataAllHomesService.findByZipcodeOrderByTimeAsc(zip);
            String key = "zillow/Zip_Zhvi_AllHomes/" + zip + ".json";
            List<TimeValueItemResult> timeSeriesDataAllHomesList = downloadService.downloadTimeValuesFromOSS(key);

            List<String> photos = listHubPhotoService.selectOSSUrlByBean(id, count);
            //photos.forEach(item -> System.err.println(item.toString()));
            model.addAttribute("photos", photos); //房源图片

            houseBaseInfo(model, listHub); //房源基本信息
            houseCharacteristics(model, listHub); //房源特征

            //学校
            com.youhome.service.result.School school = homeJunctionService.school(zip);
            model.addAttribute("school", school);
            schoolAttendanceArea(model, listHub);

            commuteIndex(model, truliaDataWithBLOBs); //通勤指数
            populationRatio(model, zip); //本区域族裔比例
            //zillow(model, zip); //zillow 相关数据
            zillow(model, zip,regionType,3); //zillow 相关数据
            homeJunction(model, state, city, county, zip); // homejunction 相关信息

            housePriceMedianSalesPriceRatio(model, listHub, truliaDataWithBLOBs); //此房源价格与附近价格对比
            listings(model, listHub); //房源介绍
            housePriceForecast(model, zip, listHub, truliaDataWithBLOBs); //房价预测 （本房源与zip房源）
            affordability(model, zip); //购房压力指数
            rentByZip(model, zip); //房租走势
            mom(model, timeSeriesDataAllHomesList); //房价环比增长率
            yoy(model, timeSeriesDataAllHomesList); //房价同比增长率

            condoRentTrendResult(model, zip); //公寓房价变化(condo房价变化)
            sFRRentTrendResult(model, zip); //独栋别墅(SFR)房价变化(SFR房价变化)

            house_Prices_Rents_Rewards(model, zip); //房价/租金/租金回报关系
            stateUS(model, zip); //state/US房价变化
            //poi(model, listHub); //房源周边景点
            poi2(model, listHub); //房源周边景点
            schoolPolygon(model, listHub, school);
            school_point_coordinates(model, listHub, school);
            school_polygon_coordinates(model, listHub, school); //学区范围
//        Zip_MedianListingPrice_1Bedroom_Line_Chart(model, zip);
//        Zip_MedianListingPrice_1Bedroom_Time_Chart(model, zip);
            System.err.println(((System.currentTimeMillis() - startTime) / 1000) + "s");

            if (StringUtils.isEmpty(template)) {
                return "free";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return template;
    }

    @GetMapping(value = "/charge/{id}")
    public String charge(Model model, @PathVariable String id, String template, Integer count,String regionType) {
        try {
            long startTime = System.currentTimeMillis();
            ListHub listHub = listHubService.selectByPrimaryKey(id);

            String zip = listHub.getZip(); // 邮编
            String state = listHub.getProvince(); //州
            String city = listHub.getCity(); // 市
            String county = listHub.getCounty(); //郡县

            TruliaDataWithBLOBs truliaDataWithBLOBs = null;
            if (!StringUtils.isEmpty(zip)) {
                truliaDataWithBLOBs = truliaDataService.selectByZipcode(zip);
            }
            //List<TimeSeriesDataAllHomes> timeSeriesDataAllHomesList = timeSeriesDataAllHomesService.findByZipcodeOrderByTimeAsc(zip);
            String key = "zillow/Zip_Zhvi_AllHomes/" + zip + ".json";
            List<TimeValueItemResult> timeSeriesDataAllHomesList = downloadService.downloadTimeValuesFromOSS(key);

            List<String> photos = listHubPhotoService.selectOSSUrlByBean(id, count);

            photos.forEach(item -> System.err.println(item.toString()));
            model.addAttribute("photos", photos); //房源图片

            houseBaseInfo(model, listHub); //房源基本信息
            houseCharacteristics(model, listHub); //房源特征

            //学校
            com.youhome.service.result.School school = homeJunctionService.school(zip);
            model.addAttribute("school", school);
            schoolAttendanceArea(model, listHub);

            commuteIndex(model, truliaDataWithBLOBs); //通勤指数
            populationRatio(model, zip); //本区域族裔比例
            //zillow(model, zip); //zillow 相关数据
            zillow(model, zip,regionType,3); //zillow 相关数据
            homeJunction(model, state, city, county, zip); // homejunction 相关信息

            housePriceMedianSalesPriceRatio(model, listHub, truliaDataWithBLOBs); //此房源价格与附近价格对比
            listings(model, listHub); //房源介绍
            housePriceForecast(model, zip, listHub, truliaDataWithBLOBs); //房价预测 （本房源与zip房源）
            affordability(model, zip); //购房压力指数
            rentByZip(model, zip); //房租走势
            mom(model, timeSeriesDataAllHomesList); //房价环比增长率
            yoy(model, timeSeriesDataAllHomesList); //房价同比增长率

            condoRentTrendResult(model, zip); //公寓房价变化(condo房价变化)
            sFRRentTrendResult(model, zip); //独栋别墅(SFR)房价变化(SFR房价变化)
            house_Prices_Rents_Rewards(model, zip); //房价/租金/租金回报关系
            stateUS(model, zip); //state/US房价变化
            //poi(model, listHub); //房源周边景点
            poi2(model, listHub); //房源周边景点
            schoolPolygon(model, listHub, school);
            school_point_coordinates(model, listHub, school);
            school_polygon_coordinates(model, listHub, school); //学区范围

            System.err.println(((System.currentTimeMillis() - startTime) / 1000) + "s");

            if (StringUtils.isEmpty(template)) {
                return "charge";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return template;
    }

    /**
     * 通勤指数
     *
     * @param model
     * @param truliaData
     */
    public void commuteIndex(Model model, TruliaDataWithBLOBs truliaData) {
        CommuteIndexResult commuteIndexResult = null;
        if (truliaData != null) {
            commuteIndexResult = new CommuteIndexResult();
            //骑车通勤比例%
            commuteIndexResult.setBike(truliaData.getCommuteBike());
            //驾车通勤比例%
            commuteIndexResult.setCar(truliaData.getCommuteCar());
            //步行通勤比例%
            commuteIndexResult.setFoot(truliaData.getCommuteFoot());
            //公交通勤比例%
            commuteIndexResult.setTransit(truliaData.getCommuteTransit());
        }
        model.addAttribute("CommuteIndex", commuteIndexResult);
    }

    /**
     * 本区域族裔比例
     *
     * @param model
     * @param zip
     */
    public void populationRatio(Model model, String zip) throws Exception {
        CityData cityData = cityDataService.selectByZipcode(zip);
        PopulationRatioResult populationRatio = null;
        if (cityData != null) {
            //===族裔比例===
            Double indian = cityData.getPopulationAmericanIndian();
            Double black = cityData.getPopulationBlack();
            Double hispanic = cityData.getPopulationHispanic();
            Double islander = cityData.getPopulationIslander();
            Double white = cityData.getPopulationWhite();

            populationRatio = new PopulationRatioResult();
            if (!StringUtils.isEmpty(indian)) {
                populationRatio.setIndian(indian); //美属印第安人人口
            }
            if (!StringUtils.isEmpty(black)) {
                populationRatio.setBlack(black); //非裔人口
            }
            if (!StringUtils.isEmpty(hispanic)) {
                populationRatio.setHispanic(hispanic); //拉丁裔人口
            }
            if (!StringUtils.isEmpty(islander)) {
                populationRatio.setIslander(islander); //太平洋及岛屿人口
            }
            if (!StringUtils.isEmpty(white)) {
                populationRatio.setWhite(white); //白人人口
            }
        }
        model.addAttribute("PopulationRatio", populationRatio);
    }

    /**
     * 房源特征
     *
     * @param model
     * @param listHub
     */
    public void houseCharacteristics(Model model, ListHub listHub) {
        //System.err.println("listHub:=====444==>>" + listHub.toString());
        CharacteristicsResult characteristicsResult = new CharacteristicsResult();
        if (listHub != null) {
            if (!StringUtils.isEmpty(listHub.getListingKey())) {
                String key = "json/" + listHub.getListingKey() + ".json";
                String json = downloadService.downloadJsonFromOSS(key);
                //System.err.println("json:" + json);
                if (!StringUtils.isEmpty(json)) {
                    net.sf.json.JSONObject jsonObject = net.sf.json.JSONObject.fromObject(json);
                    ObjectMapper mapper = new ObjectMapper();
                    //房源特征
                    if (jsonObject.get("detailedCharacteristics") != null && !jsonObject.get("detailedCharacteristics").equals("null")) {
                        net.sf.json.JSONObject characteristics = (net.sf.json.JSONObject) jsonObject.get("detailedCharacteristics");
                        if (characteristics != null && !characteristics.equals("null")) {
                            try {
                                DetailedCharacteristicsType detailedCharacteristicsType = mapper.readValue(characteristics.toString(), DetailedCharacteristicsType.class);
                                //电器
                                if (detailedCharacteristicsType.getAppliances() != null && !detailedCharacteristicsType.getAppliances().equals("null")) {
                                    if (detailedCharacteristicsType.getAppliances().getAppliance() != null && !detailedCharacteristicsType.getAppliances().getAppliance().equals("null")) {
                                        List<ApplianceEnum> appliance = detailedCharacteristicsType.getAppliances().getAppliance();
                                        ArrayList<String> appliances = new ArrayList<>();
                                        if (appliance != null && appliance.size() > 0) {
                                            for (ApplianceEnum item : appliance) {
                                                if (!StringUtils.isEmpty(item.getValue())) {
                                                    appliances.add(item.getValue());
                                                }
                                            }
                                        }
                                        characteristicsResult.setAppliances(appliances);
                                    }
                                }
                                //建筑风格
                                if (detailedCharacteristicsType.getArchitectureStyle() != null && !detailedCharacteristicsType.getArchitectureStyle().equals("null")) {
                                    String architectureStyle = detailedCharacteristicsType.getArchitectureStyle().getValue();
                                    //detailedCharacteristics.setArchitecture_style(architectureStyle);
                                }

                                //制冷系统
                                if (detailedCharacteristicsType.getCoolingSystems() != null && !detailedCharacteristicsType.getCoolingSystems().equals("null")) {
                                    if (detailedCharacteristicsType.getCoolingSystems().getCoolingSystem() != null && !detailedCharacteristicsType.getCoolingSystems().getCoolingSystem().equals("null")) {
                                        List<CoolingSystemEnum> coolingSystem = detailedCharacteristicsType.getCoolingSystems().getCoolingSystem();
                                        ArrayList<String> coolingSystems = new ArrayList<>();
                                        if (coolingSystem != null && coolingSystem.size() > 0) {
                                            for (CoolingSystemEnum item : coolingSystem) {
                                                if (!StringUtils.isEmpty(item.getValue())) {
                                                    coolingSystems.add(item.getValue());
                                                }
                                            }
                                        }
                                        characteristicsResult.setCooling_systems(coolingSystems);
                                    }
                                }

                                //室外装修
                                if (detailedCharacteristicsType.getExteriorTypes() != null && !detailedCharacteristicsType.getExteriorTypes().equals("null")) {
                                    if (detailedCharacteristicsType.getExteriorTypes().getExteriorType() != null && !detailedCharacteristicsType.getExteriorTypes().getExteriorType().equals("null")) {
                                        List<ExteriorFinishEnum> exteriorType = detailedCharacteristicsType.getExteriorTypes().getExteriorType();
                                        ArrayList<String> exteriorTypes = new ArrayList<>();
                                        if (exteriorType != null && exteriorType.size() > 0) {
                                            for (ExteriorFinishEnum item : exteriorType) {
                                                if (!StringUtils.isEmpty(item.getValue())) {
                                                    exteriorTypes.add(item.getValue());
                                                }
                                            }
                                        }
                                        characteristicsResult.setExterior_types(exteriorTypes);
                                    }
                                }

                                //地板
                                if (detailedCharacteristicsType.getFloorCoverings() != null && !detailedCharacteristicsType.getFloorCoverings().equals("null")) {
                                    if (detailedCharacteristicsType.getFloorCoverings().getFloorCovering() != null && !detailedCharacteristicsType.getFloorCoverings().getFloorCovering().equals("null")) {
                                        List<FlooringMaterialEnum> floorCovering = detailedCharacteristicsType.getFloorCoverings().getFloorCovering();
                                        ArrayList<String> floorCoverings = new ArrayList<>();
                                        if (floorCovering != null && floorCovering.size() > 0) {
                                            for (FlooringMaterialEnum item : floorCovering) {
                                                if (!StringUtils.isEmpty(item.getValue())) {
                                                    floorCoverings.add(item.getValue());
                                                }
                                            }
                                        }
                                        characteristicsResult.setFloor_coverings(floorCoverings);
                                    }
                                }

                                //供暖(燃料)
                                if (detailedCharacteristicsType.getHeatingFuels() != null && !detailedCharacteristicsType.getHeatingFuels().equals("null")) {
                                    if (detailedCharacteristicsType.getHeatingFuels().getHeatingFuel() != null && !detailedCharacteristicsType.getHeatingFuels().getHeatingFuel().equals("null")) {
                                        List<FuelEnum> heatingFuel = detailedCharacteristicsType.getHeatingFuels().getHeatingFuel();
                                        ArrayList<String> heatingFuels = new ArrayList<>();
                                        if (heatingFuel != null && heatingFuel.size() > 0) {
                                            for (FuelEnum item : heatingFuel) {
                                                if (!StringUtils.isEmpty(item.getValue())) {
                                                    heatingFuels.add(item.getValue());
                                                }
                                            }
                                        }
                                        characteristicsResult.setHeating_fuels(heatingFuels);
                                    }
                                }

                                //供暖系统
                                if (detailedCharacteristicsType.getHeatingSystems() != null && !detailedCharacteristicsType.getHeatingSystems().equals("null")) {
                                    if (detailedCharacteristicsType.getHeatingSystems().getHeatingSystem() != null && !detailedCharacteristicsType.getHeatingSystems().getHeatingSystem().equals("null")) {
                                        List<HeatingSystemEnum> heatingSystem = detailedCharacteristicsType.getHeatingSystems().getHeatingSystem();
                                        ArrayList<String> heatingSystems = new ArrayList<>();
                                        if (heatingSystem != null && heatingSystem.size() > 0) {
                                            for (HeatingSystemEnum item : heatingSystem) {
                                                if (!StringUtils.isEmpty(item.getValue())) {
                                                    heatingSystems.add(item.getValue());
                                                }
                                            }
                                        }
                                        characteristicsResult.setHeating_systems(heatingSystems);
                                    }
                                }
                                //车库
                                if (detailedCharacteristicsType.getParkingTypes() != null && !detailedCharacteristicsType.getParkingTypes().equals("null")) {
                                    if (detailedCharacteristicsType.getParkingTypes().getParkingType() != null && !detailedCharacteristicsType.getParkingTypes().getParkingType().equals("null")) {
                                        List<ParkingEnum> parkingType = detailedCharacteristicsType.getParkingTypes().getParkingType();
                                        ArrayList<String> parkingTypes = new ArrayList<>();
                                        if (parkingType != null && parkingType.size() > 0) {
                                            for (ParkingEnum item : parkingType) {
                                                if (!StringUtils.isEmpty(item.getValue())) {
                                                    parkingTypes.add(item.getValue());
                                                }
                                            }
                                        }
                                        characteristicsResult.setParking_types(parkingTypes);
                                    }
                                }
                                //屋顶类型
                                if (detailedCharacteristicsType.getRoofTypes() != null && !detailedCharacteristicsType.getRoofTypes().equals("null")) {
                                    if (detailedCharacteristicsType.getRoofTypes().getRoofType() != null && !detailedCharacteristicsType.getRoofTypes().getRoofType().equals("null")) {
                                        List<RoofMaterialEnum> roofType = detailedCharacteristicsType.getRoofTypes().getRoofType();
                                        ArrayList<String> roofTypes = new ArrayList<>();
                                        if (roofType != null && roofType.size() > 0) {
                                            for (RoofMaterialEnum item : roofType) {
                                                if (!StringUtils.isEmpty(item.getValue())) {
                                                    roofTypes.add(item.getValue());
                                                }
                                            }
                                        }
                                        characteristicsResult.setRoof_types(roofTypes);
                                    }
                                }

                                //房间
                                if (detailedCharacteristicsType.getRooms() != null && !detailedCharacteristicsType.getRooms().equals("null")) {
                                    if (detailedCharacteristicsType.getRooms().getRoom() != null && !detailedCharacteristicsType.getRooms().getRoom().equals("null")) {
                                        List<RoomCategoryEnum> room = detailedCharacteristicsType.getRooms().getRoom();
                                        ArrayList<String> rooms = new ArrayList<>();
                                        if (room != null && room.size() > 0) {
                                            for (RoomCategoryEnum item : room) {
                                                if (!StringUtils.isEmpty(item.getValue())) {
                                                    rooms.add(item.getValue());
                                                }
                                            }
                                        }
                                        //detailedCharacteristics.setRooms(rooms);
                                    }
                                }

                                //视野类型
                                if (detailedCharacteristicsType.getViewTypes() != null && !detailedCharacteristicsType.getViewTypes().equals("null")) {
                                    if (detailedCharacteristicsType.getViewTypes().getViewType() != null && !detailedCharacteristicsType.getViewTypes().getViewType().equals("null")) {
                                        List<ViewEnum> viewType = detailedCharacteristicsType.getViewTypes().getViewType();
                                        detailedCharacteristicsType.getViewTypes().getViewType();
                                        ArrayList<String> viewTypes = new ArrayList<>();
                                        if (viewType != null && viewType.size() > 0) {
                                            for (ViewEnum item : viewType) {
                                                if (!StringUtils.isEmpty(item.getValue())) {
                                                    viewTypes.add(item.getValue());
                                                }
                                            }
                                        }
                                        characteristicsResult.setView_types(viewTypes);
                                    }
                                }

                                characteristicsResult.setHas_attic(detailedCharacteristicsType.isHasAttic());
                                //detailedCharacteristics.setHas_barbecue_area(detailedCharacteristicsType.isHasBarbecueArea());
                                characteristicsResult.setHas_basement(detailedCharacteristicsType.isHasBasement());
                                //detailedCharacteristics.setBuilding_unit_count(detailedCharacteristicsType.getBuildingUnitCount());
                                characteristicsResult.setIs_cable_ready(detailedCharacteristicsType.isIsCableReady());
                                characteristicsResult.setHas_ceiling_fan(detailedCharacteristicsType.isHasCeilingFan());
                                characteristicsResult.setCondo_floor_num(detailedCharacteristicsType.getCondoFloorNum());
                                characteristicsResult.setHas_deck(detailedCharacteristicsType.isHasDeck());
                                characteristicsResult.setHas_disabled_access(detailedCharacteristicsType.isHasDisabledAccess());
                                characteristicsResult.setHas_dock(detailedCharacteristicsType.isHasDock());
                                characteristicsResult.setHas_doorman(detailedCharacteristicsType.isHasDoorman());
                                characteristicsResult.setHas_double_pane_windows(detailedCharacteristicsType.isHasDoublePaneWindows());
                                characteristicsResult.setHas_elevator(detailedCharacteristicsType.isHasElevator());
                                characteristicsResult.setHas_fireplace(detailedCharacteristicsType.isHasFireplace());
                                characteristicsResult.setHas_garden(detailedCharacteristicsType.isHasGarden());
                                //detailedCharacteristics.setHas_gated_entry(detailedCharacteristicsType.isHasGatedEntry());
                                characteristicsResult.setHas_greenhouse(detailedCharacteristicsType.isHasGreenhouse());
                                characteristicsResult.setHas_hot_tub_spa(detailedCharacteristicsType.isHasHotTubSpa());
                                characteristicsResult.setIntercom(detailedCharacteristicsType.isIntercom());
                                characteristicsResult.setHas_jetted_bath_tub(detailedCharacteristicsType.isHasJettedBathTub());
                                characteristicsResult.setHas_lawn(detailedCharacteristicsType.isHasLawn());
                                //detailedCharacteristics.setLegal_description(detailedCharacteristicsType.getLegalDescription());
                                //detailedCharacteristics.setHas_mother_in_law(detailedCharacteristicsType.isHasMotherInLaw());
                                characteristicsResult.setIs_new_construction(detailedCharacteristicsType.isIsNewConstruction());
                                characteristicsResult.setNum_floors(detailedCharacteristicsType.getNumFloors());
                                characteristicsResult.setNum_parking_spaces(detailedCharacteristicsType.getNumParkingSpaces());
                                characteristicsResult.setHas_patio(detailedCharacteristicsType.isHasPatio());
                                characteristicsResult.setHas_pond(detailedCharacteristicsType.isHasPond());
                                characteristicsResult.setHas_pool(detailedCharacteristicsType.isHasPool());
                                characteristicsResult.setHas_porch(detailedCharacteristicsType.isHasPorch());
                                // detailedCharacteristics.setRoom_count(detailedCharacteristicsType.getRoomCount());
                                characteristicsResult.setHas_rv_parking(detailedCharacteristicsType.isHasRVParking());
                                characteristicsResult.setHas_sauna(detailedCharacteristicsType.isHasSauna());
                                characteristicsResult.setHas_security_system(detailedCharacteristicsType.isHasSecuritySystem());
                                characteristicsResult.setHas_skylight(detailedCharacteristicsType.isHasSkylight());
                                characteristicsResult.setHas_sports_court(detailedCharacteristicsType.isHasSportsCourt());
                                characteristicsResult.setHas_sprinkler_system(detailedCharacteristicsType.isHasSprinklerSystem());
                                characteristicsResult.setHas_vaulted_ceiling(detailedCharacteristicsType.isHasVaultedCeiling());
                                characteristicsResult.setIs_water_front(detailedCharacteristicsType.isIsWaterfront());
                                characteristicsResult.setHas_wet_bar(detailedCharacteristicsType.isHasWetBar());
                                //detailedCharacteristics.setWhat_owner_loves(detailedCharacteristicsType.getWhatOwnerLoves());
                                characteristicsResult.setIs_wired(detailedCharacteristicsType.isIsWired());
                            } catch (IOException e) {
                                e.printStackTrace();
                            }

                        }
                    }

                }

            }
        }

        //System.err.println("characteristicsResult:" + characteristicsResult.toString());
        List<KeyValueResult> items = new ArrayList<>();
        //try {
        //String json = new String(IOUtils.readFully(translationResource.getInputStream(), -1, true));

        String json = translationService.getTranslationDictJson();
//            Locale locale = LocaleContextHolder.getLocale();
//            if (locale.equals(Locale.SIMPLIFIED_CHINESE)) {
//                json = new String(IOUtils.readFully(translationResource.getInputStream(), -1, true));
//            } else if (locale.equals(Locale.US)) {
//                json = new String(IOUtils.readFully(translationResourceEn.getInputStream(), -1, true));
//            } else {
//                json = new String(IOUtils.readFully(translationResource.getInputStream(), -1, true));
//            }

        JSONObject jsonObject = (JSONObject) JSONObject.parse(json);
        //System.err.println("jsonObject:=="+jsonObject.get("address"));
        //System.err.println(json);
        Field[] fields = characteristicsResult.getClass().getDeclaredFields();
        for (Field field : fields) {
            KeyValueResult keyValueResult = new KeyValueResult();
            String key = String.valueOf(jsonObject.get(field.getName()));
            String value = null;
           // System.err.println("field.type:" + field.getType().toString());
            if ((getFieldValueByName(field.getName(), characteristicsResult)) instanceof List) {
//                System.err.println("field.type.list:" + field.getType().toString());
//                System.err.println("field.type.list:" + getFieldValueByName(field.getName(), characteristicsResult));
                List<String> va = (List<String>) getFieldValueByName(field.getName(), characteristicsResult);
                List<String> values = new ArrayList<>();
                va.forEach(i -> {
                    String val = (String) jsonObject.get(i.toString());
                    if (StringUtils.isEmpty(val)) {
                        val = i.toString();
                    }
                    values.add(val);
                });
                value = String.join(",", values);
            } else {

                value = String.valueOf(getFieldValueByName(field.getName(), characteristicsResult));

                value = String.valueOf(jsonObject.get(value));

                System.err.println("name:"+field.getName()+"<<==>>value:"+value);
            }

            if (!StringUtils.isEmpty(value) && !value.equals("null")) {
//                if (value.equals("true")) {
//                    value = "有";
//                } else if (value.equals("false")) {
//                    value = "无";
//                }
                keyValueResult.setKey(key);
                keyValueResult.setValue(value);
                items.add(keyValueResult);
            }
            //System.err.println(field.getName() + "===" + String.valueOf(getFieldValueByName(field.getName(), characteristicsResult)));
        }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }


        System.err.println(items.toString());
        model.addAttribute("Characteristics", items);
    }

    /**
     * 房源基本信息
     *
     * @param model
     * @param listHub
     */
    public void houseBaseInfo(Model model, ListHub listHub) {
        //System.err.println("listHub:=====5555==>>"+listHub.toString());
        HouseBasicInfoResult houseBasicInfo = new HouseBasicInfoResult();

        if (listHub != null) {
            //System.err.println(houseBasicInfo);
            houseBasicInfo.setAddress(listHub.getAddress());
            houseBasicInfo.setType(listHub.getPropertySubtype());

            houseBasicInfo.setBathrooms(listHub.getBathroomCount());
            houseBasicInfo.setBedrooms(listHub.getBedroomCount());

            houseBasicInfo.setCounty(listHub.getCounty());
            houseBasicInfo.setLiving_area(listHub.getLivingArea());
            houseBasicInfo.setLot_area(listHub.getLotSize());
            houseBasicInfo.setYear(listHub.getYearBuilt());

            houseBasicInfo.setFull_bathrooms(listHub.getFullBathroomCount());
            houseBasicInfo.setHalf_bathrooms(listHub.getHalfBathroomCount());
            houseBasicInfo.setQuarter_bathrooms(listHub.getThreeQuarterBathroomCount());
            houseBasicInfo.setMls_number(listHub.getMlsNumber());
            houseBasicInfo.setListing_price(listHub.getListPrice());
            Double average_price = null;

            if (listHub.getListPrice() != null && listHub.getListPrice() > 0) {
                if (listHub.getLivingArea() != null && listHub.getLivingArea() > 0) {
                    average_price = listHub.getListPrice() / listHub.getLivingArea();
                }
            }

            houseBasicInfo.setAverage_price(DoubleUtils.format(average_price));

            if (!StringUtils.isEmpty(listHub.getListingKey())) {
                String key = "json/" + listHub.getListingKey() + ".json";
                try {
                    String json = downloadService.downloadJsonFromOSS(key);
                    if (!StringUtils.isEmpty(json)) {
                        net.sf.json.JSONObject jsonObject = net.sf.json.JSONObject.fromObject(json);

                        //社区名称
                        if (jsonObject.get("location") != null && !jsonObject.get("location").equals("null")) {
                            net.sf.json.JSONObject location = (net.sf.json.JSONObject) jsonObject.get("location");
                            if (location.get("community") != null && !location.get("community").equals("null")) {
                                net.sf.json.JSONObject community = (net.sf.json.JSONObject) location.get("community");
                                if (community.get("communityName") != null && !community.get("communityName").equals("null")) {
                                    String communityName = community.get("communityName").toString();
                                    houseBasicInfo.setCommunity(communityName);
                                }
                            }
                        }
                        ObjectMapper mapper = new ObjectMapper();
                        //房源特征
                        if (jsonObject.get("detailedCharacteristics") != null && !jsonObject.get("detailedCharacteristics").equals("null")) {
                            net.sf.json.JSONObject characteristics = (net.sf.json.JSONObject) jsonObject.get("detailedCharacteristics");
                            if (characteristics != null && !characteristics.equals("null")) {
                                DetailedCharacteristicsType detailedCharacteristicsType = mapper.readValue(characteristics.toString(), DetailedCharacteristicsType.class);
                                //建筑风格
                                if (detailedCharacteristicsType.getArchitectureStyle() != null)
                                    houseBasicInfo.setStyle(detailedCharacteristicsType.getArchitectureStyle().getValue());
                            }
                        }

                        //税
                        if (jsonObject.get("taxes") != null && !jsonObject.get("taxes").equals("null")) {
                            net.sf.json.JSONObject taxes = (net.sf.json.JSONObject) jsonObject.get("taxes");
                            if (taxes != null && !taxes.equals("null")) {
                                ListingItemType.Taxes taxes_list = mapper.readValue(taxes.toString(), ListingItemType.Taxes.class);
                                final List<TaxType> taxs = taxes_list.getTax();
                                TaxType taxType = taxs.get(0);
                                if (taxType != null) {
                                    if (taxType.getYear() != null && taxType.getAmount() != null) {
                                        houseBasicInfo.setProperty_tax(taxType.getYear().getYear() + ":" + taxType.getAmount().getValue());
                                    }
                                }
                            }
                        }
                        //物业费
                        //Home Owner Assessments Fee
                        //额外费用
                        if (!StringUtils.isEmpty(jsonObject.get("expenses")) && !jsonObject.get("expenses").equals("null")) {
                            net.sf.json.JSONObject expenses = (net.sf.json.JSONObject) jsonObject.get("expenses");
                            if (expenses != null && !expenses.equals("null")) {
                                ListingItemType.Expenses expenses_list = mapper.readValue(expenses.toString(), ListingItemType.Expenses.class);
                                for (ExpensesType item : expenses_list.getExpense()) {
                                    String value = item.getExpenseCategory().getValue();
                                    if (!StringUtils.isEmpty(value) && value.equals("Home Owner Assessments Fee")) {
                                        //物业费
                                        houseBasicInfo.setHoa_fee(item.getExpenseValue().getValue() + "/" + item.getExpenseValue().getCurrencyPeriod());
                                        break;
                                    }
                                }
                            }
                        }


                        if (!StringUtils.isEmpty(jsonObject.get("propertySubType")) && !jsonObject.get("propertySubType").equals("null")) {
                            net.sf.json.JSONObject propertySubType = jsonObject.getJSONObject("propertySubType");
                            houseBasicInfo.setOriginal_type(propertySubType.getString("value"));
                        }

                        //预估月租金
                        // Double forecastRent = timeSeriesDataAllRentMedianService.getForecastRent(listHub.getZip(), listHub.getLivingArea());
                        // houseBasicInfo.setRent_price(DoubleUtils.format(forecastRent));
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                } catch (JsonParseException e) {
                    e.printStackTrace();
                } catch (JsonMappingException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


        List<KeyValueResult> items = new ArrayList<>();
//        try {
        String json = translationService.getTranslationDictJson();
//            Locale locale = LocaleContextHolder.getLocale();
//            if (locale.equals(Locale.SIMPLIFIED_CHINESE)) {
//                json = new String(IOUtils.readFully(translationResource.getInputStream(), -1, true));
//            } else if (locale.equals(Locale.US)) {
//                json = new String(IOUtils.readFully(translationResourceEn.getInputStream(), -1, true));
//            } else {
//                json = new String(IOUtils.readFully(translationResource.getInputStream(), -1, true));
//            }
        JSONObject jsonObject = (JSONObject) JSONObject.parse(json);
        Field[] declaredFields = houseBasicInfo.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            KeyValueResult keyValueResult = new KeyValueResult();
            String key = String.valueOf(jsonObject.get(field.getName()));
            keyValueResult.setKey(key);
            String value = String.valueOf(getFieldValueByName(field.getName(), houseBasicInfo));
            //System.err.println(key + "<<=====>>" + value);
            if (StringUtils.isEmpty(value) || value.equals("null")) {
                value = "-";
            }
            keyValueResult.setValue(value);
            items.add(keyValueResult);
        }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        System.err.println("**********************************************************");
//        items.forEach(item -> {
//            System.err.println(item.getKey() + "<<=====>>" + item.getValue());
//        });

        model.addAttribute("HouseBasicInfo", items);
    }

    /**
     * zillow 数据
     *
     * @param model
     */
    public void zillow(Model model, String zip) throws CustomException {

//        1	BuyerSellerIndex_Zip.csv	买方卖方指数	non-time
        model.addAttribute("buyer_seller_index_zip_result", zillowService.get_Buyer_Seller_Index_Zip(ZillowTypeEnum.BuyerSellerIndex_Zip.getKey(), zip));

//        2	InventoryMeasure_SSA_Zip_Public.csv	滑动平均值销售存量	time
        model.addAttribute("inventory_measure_ssa_zip_public_result", zillowService.getTimeSeries(ZillowTypeEnum.InventoryMeasure_SSA_Zip_Public.getKey(), zip, 0));

//        3	InventoryMeasure_Zip_Public.csv	销售存量	time
        model.addAttribute("inventory_measure_zip_public_result", zillowService.getTimeSeries(ZillowTypeEnum.InventoryMeasure_Zip_Public.getKey(), zip, 0));

//        4	MarketHealthIndex_Zip.csv	市场健康指数	non-time
        model.addAttribute("market_health_index_zip_result", zillowService.get_Market_Health_Index_Zip(ZillowTypeEnum.MarketHealthIndex_Zip.getKey(), zip));

//        5	Zip_Listings_PriceCut_SeasAdj_AllHomes.csv	降价幅度比例-全部	time
        model.addAttribute("zip_listings_price_cut_seas_adj_all_homes_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Listings_PriceCut_SeasAdj_AllHomes.getKey(), zip, 0));

//        6	Zip_Listings_PriceCut_SeasAdj_Condominum.csv	降价幅度比例-公寓	time
        model.addAttribute("zip_listings_price_cut_seas_adj_condominum_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Listings_PriceCut_SeasAdj_Condominum.getKey(), zip, 0));

//        7	Zip_Listings_PriceCut_SeasAdj_SingleFamilyResidence.csv	降价幅度比例-独栋	time
        model.addAttribute("zip_listings_price_cut_seas_adj_single_family_residence_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Listings_PriceCut_SeasAdj_SingleFamilyResidence.getKey(), zip, 0));

//        8	Zip_Median_PriceCut_Dollar_AllHomes.csv	降价幅度金额-全部	time
        model.addAttribute("zip_median_price_cut_dollar_all_homes_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Median_PriceCut_Dollar_AllHomes.getKey(), zip, 0));

//        9	Zip_Median_PriceCut_Dollar_Condominum.csv	降价幅度金额-公寓	time
        model.addAttribute("zip_median_price_cut_dollar_condominum_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Median_PriceCut_Dollar_Condominum.getKey(), zip, 0));

//        10	Zip_Median_PriceCut_Dollar_SingleFamilyResidence.csv	降价幅度金额-独栋	time
        model.addAttribute("zip_median_price_cut_dollar_single_family_residence_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Median_PriceCut_Dollar_SingleFamilyResidence.getKey(), zip, 0));

//        11	Zip_MedianListingPrice_1Bedroom.csv	上市价格-单卧	time
        model.addAttribute("zip_median_listing_price_1bedroom_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianListingPrice_1Bedroom.getKey(), zip, 0));

//        12	Zip_MedianListingPrice_2Bedroom.csv	上市价格-双卧	time
        model.addAttribute("zip_median_listing_price_2bedroom_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianListingPrice_2Bedroom.getKey(), zip, 0));

//        13	Zip_MedianListingPrice_3Bedroom.csv	上市价格-三卧	time
        model.addAttribute("zip_median_listing_price_3bedroom_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianListingPrice_3Bedroom.getKey(), zip, 0));

//        14	Zip_MedianListingPrice_4Bedroom.csv	上市价格-四卧	time
        model.addAttribute("zip_median_listing_price_4bedroom_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianListingPrice_4Bedroom.getKey(), zip, 0));

//        15	Zip_MedianListingPrice_5BedroomOrMore.csv	上市价格-五卧或以上	time
        model.addAttribute("zip_median_listing_price_5bedroom_or_more_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianListingPrice_5BedroomOrMore.getKey(), zip, 0));

//        16	Zip_MedianListingPrice_AllHomes.csv	上市价格-全部	time
        model.addAttribute("zip_median_listing_price_all_homes_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianListingPrice_AllHomes.getKey(), zip, 0));

//        17	Zip_MedianListingPrice_CondoCoop.csv	上市价格-公寓	time
        model.addAttribute("zip_median_listing_price_condo_coop_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianListingPrice_CondoCoop.getKey(), zip, 0));

//        18	Zip_MedianListingPrice_DuplexTriplex.csv	上市价格-联式	time
        model.addAttribute("zip_median_listing_price_duplex_triplex_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianListingPrice_DuplexTriplex.getKey(), zip, 0));

//        19	Zip_MedianListingPrice_Sfr.csv	上市价格-独栋	time
        model.addAttribute("zip_median_listing_price_sfr_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianListingPrice_Sfr.getKey(), zip, 0));

//        20	Zip_MedianListingPricePerSqft_1Bedroom.csv	上市面积均价-单卧	time
        model.addAttribute("zip_median_listing_price_per_sqft_1bedroom_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianListingPricePerSqft_1Bedroom.getKey(), zip, 0));

//        21	Zip_MedianListingPricePerSqft_2Bedroom.csv	上市面积均价-双卧	time
        model.addAttribute("zip_median_listing_price_per_sqft_2bedroom_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianListingPricePerSqft_2Bedroom.getKey(), zip, 0));

//        22	Zip_MedianListingPricePerSqft_3Bedroom.csv	上市面积均价-三卧	time
        model.addAttribute("zip_median_listing_price_per_sqft_3bedroom_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianListingPricePerSqft_3Bedroom.getKey(), zip, 0));

//        23	Zip_MedianListingPricePerSqft_4Bedroom.csv	上市面积均价-四卧	time
        model.addAttribute("zip_median_listing_price_per_sqft_4bedroom_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianListingPricePerSqft_4Bedroom.getKey(), zip, 0));

//        24	Zip_MedianListingPricePerSqft_5BedroomOrMore.csv	上市面积均价-五卧	time
        model.addAttribute("zip_median_listing_price_per_sqft_5bedroom_or_more_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianListingPricePerSqft_5BedroomOrMore.getKey(), zip, 0));

//        25	Zip_MedianListingPricePerSqft_AllHomes.csv	上市面积均价-全部	time
        model.addAttribute("zip_median_listing_price_per_sqft_all_homes_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianListingPricePerSqft_AllHomes.getKey(), zip, 0));

//        26	Zip_MedianListingPricePerSqft_CondoCoop.csv	上市面积均价-公寓	time
        model.addAttribute("zip_median_listing_price_per_sqft_condo_coop_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianListingPricePerSqft_CondoCoop.getKey(), zip, 0));

//        27	Zip_MedianListingPricePerSqft_DuplexTriplex.csv	上市面积均价-联式	time
        model.addAttribute("zip_median_listing_price_per_sqft_duplex_triplex_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianListingPricePerSqft_DuplexTriplex.getKey(), zip, 0));

//        28	Zip_MedianListingPricePerSqft_Sfr.csv	上市面积均价-独栋	time
        model.addAttribute("zip_median_listing_price_per_sqft_sfr_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianListingPricePerSqft_Sfr.getKey(), zip, 0));

//        29	Zip_MedianPctOfPriceReduction_AllHomes.csv	房屋价格下调统计-全部	time
        model.addAttribute("zip_median_pct_of_price_reduction_all_homes_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianPctOfPriceReduction_AllHomes.getKey(), zip, 0));

//        30	Zip_MedianPctOfPriceReduction_Condominum.csv	房屋价格下调统计-公寓	time
        model.addAttribute("zip_median_pct_of_price_reduction_condominum_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianPctOfPriceReduction_Condominum.getKey(), zip, 0));

//        31	Zip_MedianPctOfPriceReduction_SingleFamilyResidence.csv	房屋价格下调统计-独栋	time
        model.addAttribute("zip_median_pct_of_price_reduction_single_family_residence_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianPctOfPriceReduction_SingleFamilyResidence.getKey(), zip, 0));

//        32	Zip_MedianRentalPrice_1Bedroom.csv	租金收入-单卧	time
        model.addAttribute("zip_median_rental_price_1bedroom_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPrice_1Bedroom.getKey(), zip, 0));

//        33	Zip_MedianRentalPrice_2Bedroom.csv	租金收入-双卧	time
        model.addAttribute("zip_median_rental_price_2bedroom_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPrice_2Bedroom.getKey(), zip, 0));
//        34	Zip_MedianRentalPrice_3Bedroom.csv	租金收入-三卧	time
        model.addAttribute("zip_median_rental_price_3bedroom_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPrice_3Bedroom.getKey(), zip, 0));
//        35	Zip_MedianRentalPrice_4Bedroom.csv	租金收入-四卧	time
        model.addAttribute("zip_median_rental_price_4bedroom_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPrice_4Bedroom.getKey(), zip, 0));
//        36	Zip_MedianRentalPrice_5BedroomOrMore.csv	租金收入-五卧或以上	time
        model.addAttribute("zip_median_rental_price_5bedroom_or_more_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPrice_5BedroomOrMore.getKey(), zip, 0));
//        37	Zip_MedianRentalPrice_AllHomes.csv	租金收入-全部	time
        model.addAttribute("zip_median_rental_price_all_homes_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPrice_AllHomes.getKey(), zip, 0));
//        38	Zip_MedianRentalPrice_CondoCoop.csv	租金收入-公寓	time
        model.addAttribute("zip_median_rental_price_condo_coop_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPrice_CondoCoop.getKey(), zip, 0));
//        39	Zip_MedianRentalPrice_DuplexTriplex.csv	租金收入-联式	time
        model.addAttribute("zip_median_rental_price_duplex_triplex_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPrice_DuplexTriplex.getKey(), zip, 0));
//        40	Zip_MedianRentalPrice_Mfr5Plus.csv	租金收入-多户	time
        model.addAttribute("zip_median_rental_price_mfr_5plus_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPrice_Mfr5Plus.getKey(), zip, 0));
//        41	Zip_MedianRentalPrice_Sfr.csv	租金收入-独栋	time
        model.addAttribute("zip_median_rental_price_sfr_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPrice_Sfr.getKey(), zip, 0));
//        42	Zip_MedianRentalPrice_Studio.csv	租金收入-独间	time
        model.addAttribute("zip_median_rental_price_studio_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPrice_Studio.getKey(), zip, 0));
//        43	Zip_MedianRentalPricePerSqft_1Bedroom.csv	租金面积均价-单卧	time
        model.addAttribute("zip_median_rental_price_per_sqft_1bedroom_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPricePerSqft_1Bedroom.getKey(), zip, 0));
//        44	Zip_MedianRentalPricePerSqft_2Bedroom.csv	租金面积均价-双卧	time
        model.addAttribute("zip_median_rental_price_per_sqft_2bedroom_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPricePerSqft_2Bedroom.getKey(), zip, 0));
//        45	Zip_MedianRentalPricePerSqft_3Bedroom.csv	租金面积均价-三卧	time
        model.addAttribute("zip_median_rental_price_per_sqft_3bedroom_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPricePerSqft_3Bedroom.getKey(), zip, 0));
//        46	Zip_MedianRentalPricePerSqft_4Bedroom.csv	租金面积均价-四卧	time
        model.addAttribute("zip_median_rental_price_per_sqft_4bedroom_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPricePerSqft_4Bedroom.getKey(), zip, 0));
//        47	Zip_MedianRentalPricePerSqft_5BedroomOrMore.csv	租金面积均价-五卧或以上	time
        model.addAttribute("zip_median_rental_price_per_sqft_5bedroom_or_more_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPricePerSqft_5BedroomOrMore.getKey(), zip, 0));
//        48	Zip_MedianRentalPricePerSqft_AllHomes.csv	租金面积均价-全部	time
        model.addAttribute("zip_median_rental_price_per_sqft_all_homes_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPricePerSqft_AllHomes.getKey(), zip, 0));
//        49	Zip_MedianRentalPricePerSqft_CondoCoop.csv	租金面积均价-公寓	time
        model.addAttribute("zip_median_rental_price_per_sqft_condo_coop_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPricePerSqft_CondoCoop.getKey(), zip, 0));
//        50	Zip_MedianRentalPricePerSqft_DuplexTriplex.csv	租金面积均价-联式	time
        model.addAttribute("zip_median_rental_price_per_sqft_duplex_triplex_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPricePerSqft_DuplexTriplex.getKey(), zip, 0));
//        51	Zip_MedianRentalPricePerSqft_Mfr5Plus.csv	租金面积均价-多户	time
        model.addAttribute("zip_median_rental_price_per_sqft_mfr_5plus_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPricePerSqft_Mfr5Plus.getKey(), zip, 0));
//        52	Zip_MedianRentalPricePerSqft_Sfr.csv	租金面积均价-独栋	time
        model.addAttribute("zip_median_rental_price_per_sqft_sfr_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPricePerSqft_Sfr.getKey(), zip, 0));
//        53	Zip_MedianRentalPricePerSqft_Studio.csv	租金面积均价-独间	time
        model.addAttribute("zip_median_rental_price_per_sqft_studio_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianRentalPricePerSqft_Studio.getKey(), zip, 0));
//        54	Zip_MedianValuePerSqft_AllHomes.csv	房屋面积估值-全部	time
        model.addAttribute("zip_median_value_per_sqft_all_homes_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianValuePerSqft_AllHomes.getKey(), zip, 0));
//        55	Zip_PctOfHomesDecreasingInValues_AllHomes.csv	房屋估值下调统计-全部	time
        model.addAttribute("zip_pct_of_homes_decreasing_in_values_all_homes_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_PctOfHomesDecreasingInValues_AllHomes.getKey(), zip, 0));
//        56	Zip_PctOfHomesIncreasingInValues_AllHomes.csv	房屋估值上升统计-全部	time
        model.addAttribute("zip_pct_of_homes_increasing_in_values_all_homes_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_PctOfHomesIncreasingInValues_AllHomes.getKey(), zip, 0));
//        57	Zip_PctOfListingsWithPriceReductions_AllHomes.csv	上市价格下调统计-全部	time
        model.addAttribute("zip_pct_of_listings_with_price_reductions_all_homes_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_PctOfListingsWithPriceReductions_AllHomes.getKey(), zip, 0));
//        58	Zip_PctOfListingsWithPriceReductions_Condominum.csv	上市价格下调统计-公寓	time
        model.addAttribute("zip_pct_of_listings_with_price_reductions_condominum_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_PctOfListingsWithPriceReductions_Condominum.getKey(), zip, 0));
//        59	Zip_PctOfListingsWithPriceReductions_SingleFamilyResidence.csv	上市价格下调统计-独栋	time
        model.addAttribute("zip_pct_of_listings_with_price_reductions_single_family_residence_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_PctOfListingsWithPriceReductions_SingleFamilyResidence.getKey(), zip, 0));
//        60	Zip_PriceToRentRatio_AllHomes.csv	租售比-全部	time
        model.addAttribute("zip_price_to_rent_ratio_all_homes_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_PriceToRentRatio_AllHomes.getKey(), zip, 0));
//        61	Zip_Zhvi_1bedroom.csv	房屋价格指数-单卧	time
        model.addAttribute("zip_zhvi_1bedroom_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Zhvi_1bedroom.getKey(), zip, 0));
//        62	Zip_Zhvi_2bedroom.csv	房屋价格指数-双卧	time
        model.addAttribute("zip_zhvi_2bedroom_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Zhvi_2bedroom.getKey(), zip, 0));
//        63	Zip_Zhvi_3bedroom.csv	房屋价格指数-三卧	time
        model.addAttribute("zip_zhvi_3bedroom_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Zhvi_3bedroom.getKey(), zip, 0));
//        64	Zip_Zhvi_4bedroom.csv	房屋价格指数-四卧	time
        model.addAttribute("zip_zhvi_4bedroom_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Zhvi_4bedroom.getKey(), zip, 0));
//        65	Zip_Zhvi_5BedroomOrMore.csv	房屋价格指数-五卧或以上	time
        model.addAttribute("zip_zhvi_5bedroom_or_more_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Zhvi_5BedroomOrMore.getKey(), zip, 0));
//        66	Zip_Zhvi_AllHomes.csv	房屋价格指数-全部	time
        model.addAttribute("zip_zhvi_all_homes_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Zhvi_AllHomes.getKey(), zip, 0));
//        67	Zip_Zhvi_BottomTier_yoy.csv	房屋价格指数-底层-年化同比	time
        model.addAttribute("zip_zhvi_bottom_tier_yoy_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Zhvi_BottomTier_yoy.getKey(), zip, 0));
//        68	Zip_Zhvi_BottomTier.csv	房屋价格指数-底层	time
        model.addAttribute("zip_zhvi_bottom_tier_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Zhvi_BottomTier.getKey(), zip, 0));
//        69	Zip_Zhvi_Condominum.csv	房屋价格指数-公寓	time
        model.addAttribute("zip_zhvi_condominum_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Zhvi_Condominum.getKey(), zip, 0));
//        70	Zip_Zhvi_MiddleTier_yoy.csv	房屋价格指数-中层-年化同比	time
        model.addAttribute("zip_zhvi_middle_tier_yoy_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Zhvi_MiddleTier_yoy.getKey(), zip, 0));
//        71	Zip_Zhvi_MiddleTier.csv	房屋价格指数-中层	time
        model.addAttribute("zip_zhvi_middle_tier_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Zhvi_MiddleTier.getKey(), zip, 0));
//        72	Zip_Zhvi_SingleFamilyResidence.csv	房屋价格指数-独栋	time
        model.addAttribute("zip_zhvi_single_family_residence_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Zhvi_SingleFamilyResidence.getKey(), zip, 0));
//        73	Zip_Zhvi_Summary_AllHomes.csv	房屋价格指数-全部	time
        model.addAttribute("zip_zhvi_summary_all_homes_result", zillowService.get_Zip_Zhvi_Summary_AllHomes(ZillowTypeEnum.Zip_Zhvi_Summary_AllHomes.getKey(), zip));
//        74	Zip_Zhvi_TopTier_yoy.csv	房屋价格指数-顶层-年化同比	time
        model.addAttribute("zip_zhvi_top_tier_yoy_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Zhvi_TopTier_yoy.getKey(), zip, 0));
//        75	Zip_Zhvi_TopTier.csv	房屋价格指数-顶层	time
        model.addAttribute("zip_zhvi_top_tier_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Zhvi_TopTier.getKey(), zip, 0));
//        76	Zip_Zri_AllHomes_Summary.csv	房屋租金指数-全部-汇总	non-time
        model.addAttribute("zip_zri_all_homes_summary_result", zillowService.get_Zip_Zri_AllHomes_Summary(ZillowTypeEnum.Zip_Zri_AllHomes_Summary.getKey(), zip));
//        77	Zip_Zri_AllHomes.csv	房屋租金指数-全部	time
        model.addAttribute("zip_zri_all_homes_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Zri_AllHomes.getKey(), zip, 0));
//        78	Zip_Zri_AllHomesPlusMultifamily_Summary.csv	房屋租金指数-全部加多户-汇总	non-time
        model.addAttribute("zip_zri_all_homes_plus_multifamily_summary_result", zillowService.get_Zip_Zri_AllHomes_Summary(ZillowTypeEnum.Zip_Zri_AllHomesPlusMultifamily_Summary.getKey(), zip));
//        79	Zip_Zri_AllHomesPlusMultifamily.csv	房屋租金指数-全部加多户	time
        model.addAttribute("zip_zri_all_homes_plus_multifamily_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Zri_AllHomesPlusMultifamily.getKey(), zip, 0));
//        80	Zip_Zri_MultiFamilyResidenceRental_Summary.csv	房屋租金指数-多户-汇总	non-time
        model.addAttribute("zip_zri_multifamily_residence_rental_summary_result", zillowService.get_Zip_Zri_AllHomes_Summary(ZillowTypeEnum.Zip_Zri_MultiFamilyResidenceRental_Summary.getKey(), zip));
//        81	Zip_Zri_MultiFamilyResidenceRental.csv	房屋租金指数-多户	time
        model.addAttribute("zip_zri_multifamily_residence_rental_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Zri_MultiFamilyResidenceRental.getKey(), zip, 0));
//        82	Zip_Zri_SingleFamilyResidenceRental_Summary.csv	房屋租金指数-独栋-汇总	non-time
        model.addAttribute("zip_zri_single_family_residence_rental_summary_result", zillowService.get_Zip_Zri_AllHomes_Summary(ZillowTypeEnum.Zip_Zri_SingleFamilyResidenceRental_Summary.getKey(), zip));
//        83	Zip_Zri_SingleFamilyResidenceRental.csv	房屋租金指数-独栋	time
        model.addAttribute("zip_zri_single_family_residence_rental_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_Zri_SingleFamilyResidenceRental.getKey(), zip, 0));
//        84	Zip_ZriPerSqft_AllHomes.csv	房屋面积平均租金-全部	time
        model.addAttribute("zip_zri_per_sqft_all_homes_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_ZriPerSqft_AllHomes.getKey(), zip, 0));

        //2018-10-26 新增
        //85. BreakEven_PR_2018-03 租售比   non-time
        model.addAttribute("breakeven_pr_result", zillowService.get_Break_Even_PR(ZillowTypeEnum.BreakEven_PR.getKey(), zip));
        //86. Affordability_Wide_Public 贷款能力
        model.addAttribute("mortgage_affordability_result", zillowService.getTimeSeries(ZillowTypeEnum.Affordability_Wide_Public_Loan.getKey(), zip, 10));
        //87. Affordability_Wide_Public 价格收入比
        model.addAttribute("price_to_income_result", zillowService.getTimeSeries(ZillowTypeEnum.Affordability_Wide_Public_Ratio.getKey(), zip, 10));
        //88. Affordability_Wide_Public 租金能力
        model.addAttribute("rent_affordability_result", zillowService.getTimeSeries(ZillowTypeEnum.Affordability_Wide_Public_Rent.getKey(), zip, 10));
        //89. ZriForecast_Public 租金涨幅百分比预测
        model.addAttribute("zri_forecast_public_result", zillowService.get_Zri_Forecast_Public(ZillowTypeEnum.ZriForecast_Public.getKey(), zip));
        //90. SaleToListRatio_City 卖房成功比例  按城市统计
        model.addAttribute("sale_to_list_ratio_city_result", zilLowByCityService.getTimeSeriesByCity(ZillowTypeEnum.SaleToListRatio_City.getKey(), zip, 0));
        //91. DaysOnZillow_City 中位挂牌时间 以城市为准
        model.addAttribute("days_on_market_city_result", zilLowByCityService.getTimeSeriesByCity(ZillowTypeEnum.DaysOnZillow_City.getKey(), zip, 0));
        //92. Zip_MedianListingPrice_BottomTier	低端房产中位标价
        model.addAttribute("zip_median_listing_price_bottom_tier_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianListingPrice_BottomTier.getKey(), zip, 0));
        //93. Zip_MedianListingPrice_TopTier 高端房产中位标价
        model.addAttribute("zip_median_listing_price_top_tier_result", zillowService.getTimeSeries(ZillowTypeEnum.Zip_MedianListingPrice_TopTier.getKey(), zip, 0));
        //94. Sale_Counts_Zip	房产销售数量 按zip统计
        model.addAttribute("sale_counts_zip_result", zillowService.getTimeSeries(ZillowTypeEnum.Sale_Counts_Zip.getKey(), zip, 0));
        //95. Sale_Counts_Seas_Adj_City 房产销售数量 按city统计
        model.addAttribute("sale_counts_seas_adj_city_result", zilLowByCityService.getTimeSeriesByCity(ZillowTypeEnum.Sale_Counts_Seas_Adj_City.getKey(), zip, 0));
        //96. Sale_Prices_Zip 所有房产中位售价
        model.addAttribute("sale_prices_zip_result", zillowService.getTimeSeries(ZillowTypeEnum.Sale_Prices_Zip.getKey(), zip, 0));

        //97. MortgageRateJumboFixed 超大贷款利息
        model.addAttribute("mortgage_rate_jumbo_fixed_result", zillowService.get_loan_interest(ZillowTypeEnum.MortgageRateJumboFixed.getKey(), 1));
        //98. MortgageRateConventionalFixed 传统贷款利息
        model.addAttribute("mortgage_rate_conventional_fixed_result", zillowService.get_loan_interest(ZillowTypeEnum.MortgageRateConventionalFixed.getKey(), 1));

        //99. InventoryMeasure_Tiers_Metro_Public 存量房
        model.addAttribute("inventory_measure_tiers_metro_public_count_result", zillowService.inventory("count", zip)); //数量
        model.addAttribute("inventory_measure_tiers_metro_public_pct_result", zillowService.inventory("pct", zip)); //百分比

        //100. Metro_NETiers_2017Q4 负资产率 大都会
        model.addAttribute("negative_equity_metro_result", zillowService.get_Metro_NETiers(ZillowTypeEnum.Metro_NETiers.getKey(), zip));//文字
        //101. NegativeEquity_2017Q4_Public 负资产率 城市
        model.addAttribute("negative_equity_city_result", zillowService.get_NegativeEquity_Public(ZillowTypeEnum.NegativeEquity.getKey(), zip, 0)); //百分比

        // 102. MonthlyTurnover_Zip 房产换手率
        model.addAttribute("monthly_turnover_zip_result", zillowService.getTimeSeries(ZillowTypeEnum.MonthlyTurnover_Zip.getKey(), zip, 0)); //房产换手率
        // 103. ForeclosuresPer10Khomes_Zip 法拍房比例
        model.addAttribute("foreclosures_per_10k_homes_zip_result", zillowService.getTimeSeries(ZillowTypeEnum.ForeclosuresPer10Khomes_Zip.getKey(), zip, 0)); //法拍房比例
        //104. Affordability_Income 中位家庭收入 按都会区统计
        model.addAttribute("affordability_income_result", zilLowByCityService.getTimeSeriesByCity(ZillowTypeEnum.Affordability_Income.getKey(), zip, 0));
    }



    public String zillow(Model model, String zip,String dataType,Integer year) {
        if(StringUtils.isEmpty(dataType))
            dataType = "zip";
        if(StringUtils.isEmpty(year))
            year = 0;

        ZipCode zipCode = zipCodeService.selectShortByPrimaryKey(zip);

        //买卖指数 non-time
        reportZilLowService.buyer_seller_index(model, zipCode, dataType, year);

        //滑动平均值销售存量 time
        reportZilLowService.inventory_measure_ssa_public(model, zipCode, dataType, year);

        //销售存量 time
        reportZilLowService.inventory_measure_public(model, zipCode, dataType, year);

        //市场健康指数 non-time
        reportZilLowService.market_health_index(model, zipCode, dataType, year);

        //降价幅度比例-全部 time
        reportZilLowService.listings_price_cut_seas_adj_all_homes(model, zipCode, dataType, year);

        //降价幅度比例-公寓 time
        reportZilLowService.listings_price_cut_seas_adj_condominum(model, zipCode, dataType, year);

        //降价幅度比例-独栋 time
        reportZilLowService.listings_price_cut_seas_adj_single_family_residence(model, zipCode, dataType, year);

        //降价幅度金额-全部 time
        reportZilLowService.median_price_cut_dollar_all_homes(model, zipCode, dataType, year);

        //降价幅度金额-公寓 time
        reportZilLowService.median_price_cut_dollar_condominum(model, zipCode, dataType, year);

//        10	Median_PriceCut_Dollar_SingleFamilyResidence.csv	降价幅度金额-独栋	time
        reportZilLowService.median_price_cut_dollar_single_family_residence(model, zipCode, dataType, year);

//        11	MedianListingPrice_1Bedroom.csv	上市价格-单卧	time
        reportZilLowService.median_listing_price_1bedroom(model, zipCode, dataType, year);

//        12	MedianListingPrice_2Bedroom.csv	上市价格-双卧	time
        reportZilLowService.median_listing_price_2bedroom(model, zipCode, dataType, year);

//        13	MedianListingPrice_3Bedroom.csv	上市价格-三卧	time
        reportZilLowService.median_listing_price_3bedroom(model, zipCode, dataType, year);

//        14	MedianListingPrice_4Bedroom.csv	上市价格-四卧	time
        reportZilLowService.median_listing_price_4bedroom(model, zipCode, dataType, year);

//        15	MedianListingPrice_5BedroomOrMore.csv	上市价格-五卧或以上	time
        reportZilLowService.median_listing_price_5bedroom_or_more(model, zipCode, dataType, year);

//        16	MedianListingPrice_AllHomes.csv	上市价格-全部	time
        reportZilLowService.median_listing_price_all_homes(model, zipCode, dataType, year);

//        17	MedianListingPrice_CondoCoop.csv	上市价格-公寓	time
        reportZilLowService.median_listing_price_condo_coop(model, zipCode, dataType, year);

//        18	MedianListingPrice_DuplexTriplex.csv	上市价格-联式	time
        reportZilLowService.median_listing_price_duplex_triplex(model, zipCode, dataType, year);

//        19	MedianListingPrice_Sfr.csv	上市价格-独栋	time
        reportZilLowService.median_listing_price_sfr(model, zipCode, dataType, year);

//        20	MedianListingPricePerSqft_1Bedroom.csv	上市面积均价-单卧	time
        reportZilLowService.median_listing_price_per_sqft_1bedroom(model, zipCode, dataType, year);

//        21	MedianListingPricePerSqft_2Bedroom.csv	上市面积均价-双卧	time
        reportZilLowService.median_listing_price_per_sqft_2bedroom(model, zipCode, dataType, year);

//        22	MedianListingPricePerSqft_3Bedroom.csv	上市面积均价-三卧	time
        reportZilLowService.median_listing_price_per_sqft_3bedroom(model, zipCode, dataType, year);

//        23	MedianListingPricePerSqft_4Bedroom.csv	上市面积均价-四卧	time
        reportZilLowService.median_listing_price_per_sqft_4bedroom(model, zipCode, dataType, year);

//        24	MedianListingPricePerSqft_5BedroomOrMore.csv	上市面积均价-五卧	time
        reportZilLowService.median_listing_price_per_sqft_5bedroom_or_more(model, zipCode, dataType, year);

//        25	MedianListingPricePerSqft_AllHomes.csv	上市面积均价-全部	time
        reportZilLowService.median_listing_price_per_sqft_all_homes(model, zipCode, dataType, year);

//        26	MedianListingPricePerSqft_CondoCoop.csv	上市面积均价-公寓	time
        reportZilLowService.median_listing_price_per_sqft_condo_coop(model, zipCode, dataType, year);

//        27	MedianListingPricePerSqft_DuplexTriplex.csv	上市面积均价-联式	time
        reportZilLowService.median_listing_price_per_sqft_duplex_triplex(model, zipCode, dataType, year);

//        28	MedianListingPricePerSqft_Sfr.csv	上市面积均价-独栋	time
        reportZilLowService.median_listing_price_per_sqft_sfr(model, zipCode, dataType, year);



//        29	MedianPctOfPriceReduction_AllHomes.csv	房屋价格下调统计-全部	time
        reportZilLowService.median_pct_of_price_reduction_all_homes(model, zipCode, dataType, year);

//        30	MedianPctOfPriceReduction_Condominum.csv	房屋价格下调统计-公寓	time
        reportZilLowService.median_pct_of_price_reduction_condominum(model, zipCode, dataType, year);

//        31	MedianPctOfPriceReduction_SingleFamilyResidence.csv	房屋价格下调统计-独栋	time
        reportZilLowService.median_pct_of_price_reduction_single_family_residence(model, zipCode, dataType, year);


//        32	MedianRentalPrice_1Bedroom.csv	租金收入-单卧	time
        reportZilLowService.median_rental_price_1bedroom(model, zipCode, dataType, year);
//        33	MedianRentalPrice_2Bedroom.csv	租金收入-双卧	time
        reportZilLowService.median_rental_price_2bedroom(model, zipCode, dataType, year);
//        34	MedianRentalPrice_3Bedroom.csv	租金收入-三卧	time
        reportZilLowService.median_rental_price_3bedroom(model, zipCode, dataType, year);
//        35	MedianRentalPrice_4Bedroom.csv	租金收入-四卧	time
        reportZilLowService.median_rental_price_4bedroom(model, zipCode, dataType, year);
//        36	MedianRentalPrice_5BedroomOrMore.csv	租金收入-五卧或以上	time
        reportZilLowService.median_rental_price_5bedroom_or_more(model, zipCode, dataType, year);
//        37	MedianRentalPrice_AllHomes.csv	租金收入-全部	time
        reportZilLowService.median_rental_price_all_homes(model, zipCode, dataType, year);
//        38	MedianRentalPrice_CondoCoop.csv	租金收入-公寓	time
        reportZilLowService.median_rental_price_condo_coop(model, zipCode, dataType, year);
//        39	MedianRentalPrice_DuplexTriplex.csv	租金收入-联式	time
        reportZilLowService.median_rental_price_duplex_triplex(model, zipCode, dataType, year);
//        40	MedianRentalPrice_Mfr5Plus.csv	租金收入-多户	time
        reportZilLowService.median_rental_price_mfr_5plus(model, zipCode, dataType, year);
//        41	MedianRentalPrice_Sfr.csv	租金收入-独栋	time
        reportZilLowService.median_rental_price_sfr(model, zipCode, dataType, year);
//        42	MedianRentalPrice_Studio.csv	租金收入-独间	time
        reportZilLowService.median_rental_price_studio(model, zipCode, dataType, year);


//        43	MedianRentalPricePerSqft_1Bedroom.csv	租金面积均价-单卧	time
        reportZilLowService.median_rental_price_per_sqft_1bedroom_result(model, zipCode, dataType, year);
//        44	MedianRentalPricePerSqft_2Bedroom.csv	租金面积均价-双卧	time
        reportZilLowService.median_rental_price_per_sqft_2bedroom_result(model, zipCode, dataType, year);
//        45	MedianRentalPricePerSqft_3Bedroom.csv	租金面积均价-三卧	time
        reportZilLowService.median_rental_price_per_sqft_3bedroom_result(model, zipCode, dataType, year);
//        46	MedianRentalPricePerSqft_4Bedroom.csv	租金面积均价-四卧	time
        reportZilLowService.median_rental_price_per_sqft_4bedroom_result(model, zipCode, dataType, year);
//        47	MedianRentalPricePerSqft_5BedroomOrMore.csv	租金面积均价-五卧或以上	time
        reportZilLowService.median_rental_price_per_sqft_5bedroom_or_more_result(model, zipCode, dataType, year);
//        48	MedianRentalPricePerSqft_AllHomes.csv	租金面积均价-全部	time
        reportZilLowService.median_rental_price_per_sqft_all_homes_result(model, zipCode, dataType, year);
//        49	MedianRentalPricePerSqft_CondoCoop.csv	租金面积均价-公寓	time
        reportZilLowService.median_rental_price_per_sqft_condo_coop_result(model, zipCode, dataType, year);
//        50	MedianRentalPricePerSqft_DuplexTriplex.csv	租金面积均价-联式	time
        reportZilLowService.median_rental_price_per_sqft_duplex_triplex_result(model, zipCode, dataType, year);
//        51	MedianRentalPricePerSqft_Mfr5Plus.csv	租金面积均价-多户	time
        reportZilLowService.median_rental_price_per_sqft_mfr_5plus_result(model, zipCode, dataType, year);
//        52	MedianRentalPricePerSqft_Sfr.csv	租金面积均价-独栋	time
        reportZilLowService.median_rental_price_per_sqft_sfr_result(model, zipCode, dataType, year);
//        53	MedianRentalPricePerSqft_Studio.csv	租金面积均价-独间	time
        reportZilLowService.median_rental_price_per_sqft_studio_result(model, zipCode, dataType, year);


//        54	MedianValuePerSqft_AllHomes.csv	房屋面积估值-全部	time
        reportZilLowService.median_value_per_sqft_all_homes_result(model, zipCode, dataType, year);
//        55	PctOfHomesDecreasingInValues_AllHomes.csv	房屋估值下调统计-全部	time
        reportZilLowService.pct_of_homes_decreasing_in_values_all_homes_result(model, zipCode, dataType, year);
//        56	PctOfHomesIncreasingInValues_AllHomes.csv	房屋估值上升统计-全部	time
        reportZilLowService.pct_of_homes_increasing_in_values_all_homes_result(model, zipCode, dataType, year);
//        57	PctOfListingsWithPriceReductions_AllHomes.csv	上市价格下调统计-全部	time
        reportZilLowService.pct_of_listings_with_price_reductions_all_homes_result(model, zipCode, dataType, year);
//        58	PctOfListingsWithPriceReductions_Condominum.csv	上市价格下调统计-公寓	time
        reportZilLowService.pct_of_listings_with_price_reductions_condominum_result(model, zipCode, dataType, year);
//        59	PctOfListingsWithPriceReductions_SingleFamilyResidence.csv	上市价格下调统计-独栋	time
        reportZilLowService.pct_of_listings_with_price_reductions_single_family_residence_result(model, zipCode, dataType, year);
//        60	PriceToRentRatio_AllHomes.csv	租售比-全部	time
        reportZilLowService.price_to_rent_ratio_all_homes_result(model, zipCode, dataType, year);


//        61	Zhvi_1bedroom.csv	房屋价格指数-单卧	time
        reportZilLowService.zhvi_1bedroom_result(model, zipCode, dataType, year);
//        62	Zhvi_2bedroom.csv	房屋价格指数-双卧	time
        reportZilLowService.zhvi_2bedroom_result(model, zipCode, dataType, year);
//        63	Zhvi_3bedroom.csv	房屋价格指数-三卧	time
        reportZilLowService.zhvi_3bedroom_result(model, zipCode, dataType, year);
//        64	Zhvi_4bedroom.csv	房屋价格指数-四卧	time
        reportZilLowService.zhvi_4bedroom_result(model, zipCode, dataType, year);
//        65	Zhvi_5BedroomOrMore.csv	房屋价格指数-五卧或以上	time
        reportZilLowService.zhvi_5bedroom_or_more_result(model, zipCode, dataType, year);
//        66	Zhvi_AllHomes.csv	房屋价格指数-全部	time
        reportZilLowService.zhvi_all_homes_result(model, zipCode, dataType, year);
//        67	Zhvi_BottomTier_yoy.csv	房屋价格指数-底层-年化同比	time
        reportZilLowService.zhvi_bottom_tier_yoy_result(model, zipCode, dataType, year);
//        68	Zhvi_BottomTier.csv	房屋价格指数-底层	time
        reportZilLowService.zhvi_bottom_tier_result(model, zipCode, dataType, year);
//        69	Zhvi_Condominum.csv	房屋价格指数-公寓	time
        reportZilLowService.zhvi_condominum_result(model, zipCode, dataType, year);
//        70	Zhvi_MiddleTier_yoy.csv	房屋价格指数-中层-年化同比	time
        reportZilLowService.zhvi_middle_tier_yoy_result(model, zipCode, dataType, year);
//        71	Zhvi_MiddleTier.csv	房屋价格指数-中层	time
        reportZilLowService.zhvi_middle_tier_result(model, zipCode, dataType, year);
//        72	Zhvi_SingleFamilyResidence.csv	房屋价格指数-独栋	time
        reportZilLowService.zhvi_single_family_residence_result(model, zipCode, dataType, year);
//        73	Zhvi_Summary_AllHomes.csv	房屋价格指数-全部	time
        reportZilLowService.zhvi_summary_all_homes_result(model, zipCode, dataType, year);
//        74	Zhvi_TopTier_yoy.csv	房屋价格指数-顶层-年化同比	time
        reportZilLowService.zhvi_top_tier_yoy_result(model, zipCode, dataType, year);
//        75	Zhvi_TopTier.csv	房屋价格指数-顶层	time
        reportZilLowService.zhvi_top_tier_result(model, zipCode, dataType, year);



//        76	Zri_AllHomes_Summary.csv	房屋租金指数-全部-汇总	non-time
        reportZilLowService.zri_all_homes_summary_result(model, zipCode, dataType, year);
//        77	Zri_AllHomes.csv	房屋租金指数-全部	time
        reportZilLowService.zri_all_homes_result(model, zipCode, dataType, year);
//        78	Zri_AllHomesPlusMultifamily_Summary.csv	房屋租金指数-全部加多户-汇总	non-time
        reportZilLowService.zri_all_homes_plus_multifamily_summary_result(model, zipCode, dataType, year);
//        79	Zri_AllHomesPlusMultifamily.csv	房屋租金指数-全部加多户	time
        reportZilLowService.zri_all_homes_plus_multifamily_result(model, zipCode, dataType, year);
//        80	Zri_MultiFamilyResidenceRental_Summary.csv	房屋租金指数-多户-汇总	non-time
        reportZilLowService.zri_multifamily_residence_rental_summary_result(model, zipCode, dataType, year);
//        81	Zri_MultiFamilyResidenceRental.csv	房屋租金指数-多户	time
        reportZilLowService.zri_multifamily_residence_rental_result(model, zipCode, dataType, year);
//        82	Zri_SingleFamilyResidenceRental_Summary.csv	房屋租金指数-独栋-汇总	non-time
        reportZilLowService.zri_single_family_residence_rental_summary_result(model, zipCode, dataType, year);
//        83	Zri_SingleFamilyResidenceRental.csv	房屋租金指数-独栋	time
        reportZilLowService.zri_single_family_residence_rental_result(model, zipCode, dataType, year);
//        84	ZriPerSqft_AllHomes.csv	房屋面积平均租金-全部	time
        reportZilLowService.zri_per_sqft_all_homes_result(model, zipCode, dataType, year);



        //2018-10-26 新增
        //85. BreakEven_PR_2018-03 租售比   non-time
        reportZilLowService.breakeven_pr_result(model, zipCode, dataType, year);


        //86. Affordability_Wide_Public 贷款能力
        reportZilLowService.mortgage_affordability_result(model, zipCode, dataType, year);


        //87. Affordability_Wide_Public 价格收入比
        reportZilLowService.price_to_income_result(model, zipCode, dataType, year);
        //88. Affordability_Wide_Public 租金能力
        reportZilLowService.rent_affordability_result(model, zipCode, dataType, year);


        //89. ZriForecast_Public 租金涨幅百分比预测
        reportZilLowService.zri_forecast_public_result(model, zipCode, dataType, year);
        //90. SaleToListRatio_City 卖房成功比例  按城市统计
        reportZilLowService.sale_to_list_ratio_city_result(model, zipCode, dataType, year);
        //91. DaysOnZillow_City 中位挂牌时间 以城市为准
        reportZilLowService.days_on_market_city_result(model, zipCode, dataType, year);
        //92. MedianListingPrice_BottomTier	低端房产中位标价
        reportZilLowService.median_listing_price_bottom_tier_result(model, zipCode, dataType, year);


        //93. MedianListingPrice_TopTier 高端房产中位标价
        reportZilLowService.median_listing_price_top_tier_result(model, zipCode, dataType, year);
        //94. Sale_Counts_Zip	房产销售数量 按zip统计
        reportZilLowService.sale_counts_result(model, zipCode, dataType, year);
        //95. Sale_Counts_Seas_Adj_City 房产销售数量 按city统计
        reportZilLowService.sale_counts_seas_adj_city_result(model, zipCode, dataType, year);
        //96. Sale_Prices_Zip 所有房产中位售价
        reportZilLowService.sale_prices_result(model, zipCode, dataType, year);

        //97. MortgageRateJumboFixed 超大贷款利息
        reportZilLowService.mortgage_rate_jumbo_fixed_result(model, zipCode, dataType, 1);
        //98. MortgageRateConventionalFixed 传统贷款利息
        reportZilLowService.mortgage_rate_conventional_fixed_result(model, zipCode, dataType, 1);

        //99. InventoryMeasure_Tiers_Metro_Public 存量房
        reportZilLowService.inventory_measure_tiers_metro_public_count_result(model, zipCode, dataType, year); //数量
        reportZilLowService.inventory_measure_tiers_metro_public_pct_result(model, zipCode, dataType, year); //百分比

        //100. Metro_NETiers_2017Q4 负资产率 大都会
        reportZilLowService.negative_equity_metro_result(model, zipCode, dataType, year);//文字
        //101. NegativeEquity_2017Q4_Public 负资产率 城市
        reportZilLowService.negative_equity_city_result(model, zipCode, dataType, year); //百分比

        // 102. MonthlyTurnover_Zip 房产换手率
        reportZilLowService.monthly_turnover_result(model, zipCode, dataType, year); //房产换手率
        // 103. ForeclosuresPer10Khomes_Zip 法拍房比例
        reportZilLowService.foreclosures_per_10k_homes_result(model, zipCode, dataType, year); //法拍房比例
        //104. Affordability_Income 中位家庭收入 按都会区统计
        reportZilLowService.affordability_income_result(model, zipCode, dataType, year);


        return "zillow";
    }

    /***
     * homejunction 数据
     * @param model
     * @param state 州
     * @param city 城市
     * @param county 郡县
     * @param zip 邮编
     */
    public void homeJunction(Model model, String state, String city, String county, String zip) {
        PopulationAgeResult populationAgeResult = new PopulationAgeResult();
        CostsResult costsResult = new CostsResult();
        AreaResult areaResult = new AreaResult();
        CrimeResult crimeResult = new CrimeResult();
        EducationResult educationResult = new EducationResult();
        EmploymentResult employmentResult = new EmploymentResult();
        GenderResult genderResult = new GenderResult();
        HouseholdResult householdResult = new HouseholdResult();
        IncomeResult incomeResult = new IncomeResult();
        PopulationResult populationResult = new PopulationResult();
        RaceResult raceResult = new RaceResult();
        WeatherResult weatherResult = new WeatherResult();

        String stateId = null;
        if (!StringUtils.isEmpty(state)) {
            HJState hjState = homeJunctionService.selectStateByAbbreviation(state);
            if (hjState != null) {
                String key = "homejunction/state/" + hjState.getId() + ".json";
                String json = downloadService.downloadJsonFromOSS(key);
                householdResult.setState(analysisHousehold(json));
                areaResult.setState(analysisArea(json));
                stateId = hjState.getId();
            }
        }

        if (!StringUtils.isEmpty(city) && !StringUtils.isEmpty(state)) {

            //city = city + ", " + state;// Manila, AR
            HJCity record_city = new HJCity();
            record_city.setStateId(stateId);
            record_city.setName(city);
            HJCity hjCity = homeJunctionService.selectCityByBean(record_city);
            if (hjCity != null) {
                String key = "homejunction/city/" + hjCity.getId() + ".json";
                String json = downloadService.downloadJsonFromOSS(key);
                householdResult.setCity(analysisHousehold(json));
                areaResult.setCity(analysisArea(json));
            }
        }

        if (!StringUtils.isEmpty(county)) {
            //county = county + ", " + state;// Manila, AR
            HJCounty county_record = new HJCounty();
            county_record.setStateId(stateId);
            county_record.setName(county);

            HJCounty hjCounty = homeJunctionService.selectCountyByBean(county_record);
            if (hjCounty != null) {
                String key = "homejunction/county/" + hjCounty.getId() + ".json";
                String json = downloadService.downloadJsonFromOSS(key);
                householdResult.setCounty(analysisHousehold(json));
            }
        }

        if (!StringUtils.isEmpty(zip)) {
            HJZipCode hjZip = hjZipCodeService.selectByZipCode(zip);
            if (hjZip != null) {
                String key = "homejunction/zip/" + hjZip.getId() + ".json";
                String json = downloadService.downloadJsonFromOSS(key);

                populationAgeResult.setZip(analysisAge(json));
                costsResult.setZip(analysisCosts(json));
                crimeResult.setZip(analysisCrime(json));
                educationResult.setZip(analysisEducation(json));
                employmentResult.setZip(analysisEmployment(json));
                genderResult.setZip(analysisGender(json));
                householdResult.setZip(analysisHousehold(json));
                incomeResult.setZip(analysisIncome(json));
                populationResult.setZip(analysisPopulation(json));
                raceResult.setZip(analysisRace(json));
                weatherResult.setZip(analysisWeather(json));
                areaResult.setZip(analysisArea(json));
            }
        }


        model.addAttribute("PopulationAgeResult", populationAgeResult); //人口年龄结构
        model.addAttribute("CostsResult", costsResult); //生活成本
        model.addAttribute("CrimeResult", crimeResult);//犯罪数据统计
        model.addAttribute("EducationResult", educationResult);//教育数据统计
        model.addAttribute("EmploymentResult", employmentResult);//就业数据统计
        model.addAttribute("GenderResult", genderResult);//性别统计
        model.addAttribute("HouseholdResult", householdResult);//同屋居住者统计
        model.addAttribute("IncomeResult", incomeResult);//收入统计
        model.addAttribute("PopulationResult", populationResult);//人口统计
        model.addAttribute("RaceResult", raceResult);//族裔统计
        model.addAttribute("WeatherResult", weatherResult);//气候数据统计
        model.addAttribute("AreaResult", areaResult);//面积统计
    }

    /**
     * 此房源价格与附近价格对比
     */
    public void housePriceMedianSalesPriceRatio(Model model, ListHub listHub, TruliaDataWithBLOBs truliaData) {
        HousePriceMedianSalesPriceRatioResult housePriceMedianSalesPriceRatioResult = null;// new HousePriceMedianSalesPriceRatioResult();
        HousePriceMedianSalesPriceRatioResult housePriceMedianSalesPriceRatioResultSQFT = null;//new HousePriceMedianSalesPriceRatioResult();
        if (listHub != null) {
            Double price = listHub.getListPrice(); //房产价格
            Double area = listHub.getLivingArea(); //面积
            String zip = listHub.getZip();  //邮编

            Double pricePerSQFT = 0.0;//房源每平方英尺单价
            if (!StringUtils.isEmpty(area) && area > 0) {
                pricePerSQFT = Double.valueOf(price / area);
            }

            //System.err.println("listHub==>>" + listHub.getListPrice());
            if (!StringUtils.isEmpty(zip)) {

//                TruliaData truliaData = truliaDataService.selectByZipcode(zip);
//                System.err.println("truliaData==>>" + truliaData.toString());
                if (truliaData != null) {

                    Double median_sales_price = truliaData.getMedianSalesPrice();  //房产售价中位数
                    //System.err.println("truliaData==median_sales_price>>" + truliaData.getMedianSalesPrice());

                    Double ratio = Double.valueOf(0);
                    if (median_sales_price != null && median_sales_price != 0) {
                        ratio = price / median_sales_price;
                    }
                    if (!StringUtils.isEmpty(price) && !StringUtils.isEmpty(median_sales_price)) {
                        housePriceMedianSalesPriceRatioResult = new HousePriceMedianSalesPriceRatioResult();
                        housePriceMedianSalesPriceRatioResult.setPrice(price);
                        housePriceMedianSalesPriceRatioResult.setMedianSalesPrice(median_sales_price);
                        housePriceMedianSalesPriceRatioResult.setRatio(ratio);
                    }

                    Double ratioSQFT = Double.valueOf(0);
                    Double zipPricePerSqFt = truliaData.getPricePerSqft(); //每平方英尺单价
                    if (!StringUtils.isEmpty(zipPricePerSqFt) && zipPricePerSqFt > 0) {
                        ratioSQFT = pricePerSQFT / zipPricePerSqFt;
                    }

                    if (!StringUtils.isEmpty(pricePerSQFT) && !StringUtils.isEmpty(zipPricePerSqFt)) {
                        housePriceMedianSalesPriceRatioResultSQFT = new HousePriceMedianSalesPriceRatioResult();
                        housePriceMedianSalesPriceRatioResultSQFT.setPrice(pricePerSQFT);
                        housePriceMedianSalesPriceRatioResultSQFT.setMedianSalesPrice(zipPricePerSqFt);
                        housePriceMedianSalesPriceRatioResultSQFT.setRatio(ratioSQFT);
                    }
                }
            }
        }

        model.addAttribute("HousePriceMedianSalesPriceRatioResult", housePriceMedianSalesPriceRatioResult); //此房源价格与附近价格对比
        model.addAttribute("HousePriceMedianSalesPriceRatioSQFTResult", housePriceMedianSalesPriceRatioResultSQFT); //此房源价格与附近价格对比（每平方英尺）

        if (housePriceMedianSalesPriceRatioResult != null) {
            DefaultCategoryDataset dataSet = new DefaultCategoryDataset();

            dataSet.addValue(housePriceMedianSalesPriceRatioResult.getPrice(), "房价对比", "此房价格");
            dataSet.addValue(housePriceMedianSalesPriceRatioResult.getMedianSalesPrice(), "房价对比", "附近均价");

            String chart = chartService.createBarChart("此房源价格与附近均价对比", dataSet);
            model.addAttribute("chart", chart); //图表
        }
    }

    /**
     * 房价预测 （本房源与zip房源）
     *
     * @param model
     * @param zipCode
     * @param truliaData
     */
    public void housePriceForecast(Model model, String zipCode, ListHub listHub, TruliaDataWithBLOBs truliaData) {
        PriceForecastResult priceForecastResult = null;//new PriceForecastResult();
        PriceForecastResult priceForecastZipResult = null;// new PriceForecastResult();

        /*
        TimeSeriesDataHomeValueForecast homeValueForecast = timeSeriesDataHomeValueForecastService.selectByZipcode(zipCode);

        //System.err.println("=============房价预测====================");
        //System.err.println(listHub.toString());
        //System.err.println(truliaData.toString());
        //System.err.println(homeValueForecast.toString());

        if (homeValueForecast != null) {
            Double rise = homeValueForecast.getValue(); //增浮率

            //本房源
            if (listHub != null) {
                Double price = listHub.getListPrice();
                System.err.println("price:" + price);
                if (!StringUtils.isEmpty(rise) && !StringUtils.isEmpty(price)) {
                    priceForecastResult = new PriceForecastResult();
                    Double forecastPrice = price * (1 + rise / 100);
                    priceForecastResult.current_price = price;
                    priceForecastResult.forecast_price = forecastPrice;
                    priceForecastResult.rise = rise;
                }
            }
            //zip房源
            if (truliaData != null) {
                Double priceZip = truliaData.getMedianSalesPrice();
                if (!StringUtils.isEmpty(rise) && !StringUtils.isEmpty(priceZip)) {
                    priceForecastZipResult = new PriceForecastResult();
                    Double forecastPriceZip = priceZip * (1 + rise / 100);
                    priceForecastZipResult.current_price = priceZip;
                    priceForecastZipResult.forecast_price = forecastPriceZip;
                    priceForecastZipResult.rise = rise;
                }
            }

        }

        model.addAttribute("PriceForecastResult", priceForecastResult); //房价预测
        model.addAttribute("priceForecastZipResult", priceForecastZipResult); //ZipCode 房价预测
        */

        Zip zip = zipService.selectByPrimaryKey(zipCode);
        if (!StringUtils.isEmpty(zip.getState()) && !StringUtils.isEmpty(zip.getZipcode())) {
            String key = "zillow/AllRegionsForePublic/" + zip.getState().toLowerCase() + "_zip_" + zip.getZipcode() + ".json";
            //System.err.println("key:" + key);
            String json = downloadService.downloadJsonFromOSS(key);
            if (!StringUtils.isEmpty(json)) {
                JSONObject jsonObject = JSON.parseObject(json);
                if (jsonObject.get("ForecastYoYPctChange") != null) {
                    Double rise = Double.valueOf(jsonObject.getString("ForecastYoYPctChange"));
                    if (!StringUtils.isEmpty(rise)) {
                        //本房源
                        if (listHub != null) {
                            Double price = listHub.getListPrice();
                            //System.err.println("price:" + price);
                            if (!StringUtils.isEmpty(rise) && !StringUtils.isEmpty(price)) {
                                priceForecastResult = new PriceForecastResult();
                                Double forecastPrice = price * (1 + rise / 100);
                                priceForecastResult.current_price = price;
                                priceForecastResult.forecast_price = forecastPrice;
                                priceForecastResult.rise = rise;
                            }
                        }
                        //zip房源
                        if (truliaData != null) {
                            Double priceZip = truliaData.getMedianSalesPrice();
                            //System.err.println("rise:" + rise + "==priceZip:" + priceZip);
                            if (!StringUtils.isEmpty(rise) && !StringUtils.isEmpty(priceZip)) {
                                priceForecastZipResult = new PriceForecastResult();
                                Double forecastPriceZip = priceZip * (1 + rise / 100);
                                priceForecastZipResult.current_price = priceZip;
                                priceForecastZipResult.forecast_price = forecastPriceZip;
                                priceForecastZipResult.rise = rise;
                                //System.err.println("priceForecastZipResult:" + priceForecastZipResult.forecast_price.toString());
                            }
                        }
                    }
                }
            }
        }
        model.addAttribute("priceForecastResult", priceForecastResult); //房价预测
        model.addAttribute("priceForecastZipResult", priceForecastZipResult); //ZipCode 房价预测
    }

    /**
     * 房价环比增长率
     *
     * @param model
     * @param list
     */
    public void mom(Model model, List<TimeValueItemResult> list) {
        /*
        // List<TimeSeriesDataAllHomes> list = timeSeriesDataAllHomesService.findByZipcodeOrderByTimeAsc(zipcode);
        List<TimeSeriesItem> moms = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            Date current_time = list.get(i).getTime();
            Double current_value = list.get(i).getValue(); //当前月的值
            Date last_month = null;
            Double last_value = 0.0;
            if (i > 0) {
                last_month = list.get(i - 1).getTime();
                last_value = list.get(i - 1).getValue(); //上月的值
                Double ratio = 0.0;
                if (last_value != 0) {
                    //房价环比增长率(moms)  环比增长率=(本期数-上期数)/上期数×100%。
                    ratio = (current_value - last_value) / last_value * 100;
                }
                TimeSeriesItem mom = new TimeSeriesItem();
                mom.setTime(DateUtils.DateToStr(current_time, "yyyy-MM"));
                mom.setValue(ratio);
                moms.add(mom);
            }
        }
        if (moms != null && moms.size() > 60) {
            Collections.reverse(moms);
            moms = moms.subList(0, 60);
            Collections.reverse(moms);
        }
        model.addAttribute("mom", moms); //房价环比增长率

        */

        List<TimeSeriesItem> moms = new ArrayList<>();
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                Date current_time = DateUtils.StrToDate(list.get(i).getTime(), "yyyy-MM");
                if (i > 0) {
                    Double ratio = 0.0;
                    if (!StringUtils.isEmpty(list.get(i).getValue()) && !StringUtils.isEmpty(list.get(i - 1).getValue())) {
                        Double current_value = Double.valueOf(list.get(i).getValue()); //当前月的值
                        Double last_value = Double.valueOf(list.get(i - 1).getValue()); //上月的值
                        if (last_value != 0) {
                            //房价环比增长率(moms)  环比增长率=(本期数-上期数)/上期数×100%。
                            ratio = (current_value - last_value) / last_value * 100;
                        }
                    }
                    TimeSeriesItem mom = new TimeSeriesItem();
                    mom.setTime(DateUtils.DateToStr(current_time, "yyyy-MM"));
                    mom.setValue(ratio);
                    moms.add(mom);
                }
            }
        }

        String time = "5";  //5年

        if (!time.equals("0")) {
            String dateFormat = "yyyy-MM";
            Date etime = new Date();
            Date btime = DateUtils.addYear(etime, -Integer.parseInt(time));
            //开始截取的时间
            String startTime = DateUtils.DateToStr(btime, dateFormat);
            Boolean flag = false; // 开始截取标识
            List<TimeSeriesItem> items = new ArrayList<>();
            if (moms != null && moms.size() > 0) {
                for (TimeSeriesItem item : moms) {
                    if (item.getTime().equalsIgnoreCase(startTime)) {
                        flag = true;  //从这个开始截取
                    }
                    if (flag) {
                        items.add(item);
                    }
                }
            }

            if (items.size() > 0) {
                model.addAttribute("mom", items); //房价环比增长率
            }
        } else {
            model.addAttribute("mom", moms); //房价环比增长率
        }

    }

    /**
     * 房价同比增长率
     *
     * @param model
     * @param list
     */
    public void yoy(Model model, List<TimeValueItemResult> list) {

        /*
        //List<TimeSeriesDataAllHomes> list =  timeSeriesDataAllHomesService.findByZipcodeOrderByTimeAsc(zipcode);
        List<TimeSeriesItem> yoys = new ArrayList<TimeSeriesItem>();
        for (int i = 0; i < list.size(); i++) {
            Date current_time = list.get(i).getTime();
            Double current_value = list.get(i).getValue();
            Date last_month = null;
            Double last_value = 0.0;
            if (i > 12) {
                last_month = list.get(i - 12).getTime();
                last_value = list.get(i - 12).getValue();
                Double ratio = 0.0;
                if (last_value != 0) {
                    ratio = (current_value - last_value) / last_value * 100;
                }
                TimeSeriesItem yoy = new TimeSeriesItem();
                yoy.setTime(DateUtils.DateToStr(current_time, "yyyy-MM"));
                yoy.setValue(ratio);
                yoys.add(yoy);
            }
        }
        if (yoys != null && yoys.size() > 60) {
            Collections.reverse(yoys);
            yoys = yoys.subList(0, 60);
            Collections.reverse(yoys);
        }
        model.addAttribute("yoy", yoys); //房价同比增长率

        */
        List<TimeSeriesItem> yoys = new ArrayList<>();
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                Date current_time = DateUtils.StrToDate(list.get(i).getTime(), "yyyy-MM");
                Double last_value = 0.0;
                if (i > 12) {
                    Double ratio = 0.0;
                    if (!StringUtils.isEmpty(list.get(i).getValue()) && !StringUtils.isEmpty(list.get(i - 12).getValue())) {
                        Double current_value = Double.valueOf(list.get(i).getValue()); //当前月的值
                        last_value = Double.valueOf(list.get(i - 12).getValue()); //上年的值
                        if (last_value != 0) {
                            //房价环比增长率(moms)  环比增长率=(本期数-上期数)/上期数×100%。
                            ratio = (current_value - last_value) / last_value * 100;
                        }
                    }
                    TimeSeriesItem mom = new TimeSeriesItem();
                    mom.setTime(DateUtils.DateToStr(current_time, "yyyy-MM"));
                    mom.setValue(ratio);
                    yoys.add(mom);
                }
            }
        }

        String time = "5"; //5年

        if (!time.equals("0")) {
            String dateFormat = "yyyy-MM";
            Date etime = new Date();
            Date btime = DateUtils.addYear(etime, -Integer.parseInt(time));
            //开始截取的时间
            String startTime = DateUtils.DateToStr(btime, dateFormat);
            Boolean flag = false; // 开始截取标识
            List<TimeSeriesItem> items = new ArrayList<>();
            if (yoys != null && yoys.size() > 0) {
                for (TimeSeriesItem item : yoys) {
                    if (item.getTime().equalsIgnoreCase(startTime)) {
                        flag = true;  //从这个开始截取
                    }
                    if (flag) {
                        items.add(item);
                    }
                }
            }
            if (items.size() > 0) {
                model.addAttribute("yoy", items); //房价同比增长率
            }
        } else {
            model.addAttribute("yoy", yoys); //房价同比增长率
        }
    }

    /**
     * 房源介绍
     *
     * @param model
     * @param listHub
     */
    public void listings(Model model, ListHub listHub) {
        String key = "json/" + listHub.getListingKey() + ".json";
        TranslationResult listings = null;
        try {
            String json = downloadService.downloadJsonFromOSS(key);
            if (!StringUtils.isEmpty(json)) {
                net.sf.json.JSONObject dataJson = net.sf.json.JSONObject.fromObject(json);
                if (dataJson.get("listingDescription") != null && !dataJson.get("listingDescription").equals("null")) {
                    String listingDescription = (String) dataJson.get("listingDescription");
                    listings = translateService.trans(listHub.getHouseId(), listingDescription);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //System.err.println("listings===>>" + listings.toString());
        model.addAttribute("listings", listings);
    }

    /**
     * 购房指数
     *
     * @param model
     * @param zipCode
     */
    public void affordability(Model model, String zipCode) {
        /*
        AffordabilityResult affordabilityResult = new AffordabilityResult();
        Zip zip = zipService.selectByPrimaryKey(zipCode);

        System.err.println("====================购房指数==============================");
        System.err.println(zip.toString());
        if (zip != null) {
            String metro = zip.getMetro();
            System.err.println("metro:" + metro);
            List<TimeSeriesDataAffordability> list = timeSeriesDataAffordabilityService.findThreeByMetro(metro);
            for (TimeSeriesDataAffordability item : list) {
                switch (item.getSubtype()) {
                    case "Price To Income":
                        affordabilityResult.setPrice_to_income(item.getValue());
                        break;
                    case "Mortgage Affordability":
                        affordabilityResult.setMortgage_affordability(item.getValue());
                        break;
                    case "Rent Affordability":
                        affordabilityResult.setRent_affordability(item.getValue());
                        break;
                }
            }
        }
        model.addAttribute("AffordabilityResult", affordabilityResult); //购房压力指数

        */
        //System.err.println("==affordabilityResult===");
        Affordability affordability = null;
        Zip zip = zipService.selectByPrimaryKey(zipCode);
        if (zip != null && !StringUtils.isEmpty(zip.getMetro())) {

            String metro = StringUtil.replaceBlankAndComma(zip.getMetro());


            String price_to_income = "zillow/Affordability_Wide_Public/" + metro + "_price_to_income.json";
            String mortgage_affordability = "zillow/Affordability_Wide_Public/" + metro + "_mortgage_affordability.json";
            String rent_affordability = "zillow/Affordability_Wide_Public/" + metro + "_rent_affordability.json";

            List<TimeValueItemResult> timeValueItemResults_price_to_income = downloadService.downloadTimeValuesFromOSS(price_to_income);
            List<TimeValueItemResult> timeValueItemResults_mortgage_affordability = downloadService.downloadTimeValuesFromOSS(mortgage_affordability);
            List<TimeValueItemResult> timeValueItemResults_rent_affordability = downloadService.downloadTimeValuesFromOSS(rent_affordability);

            //System.err.println("timeValueItemResults_price_to_income:" + timeValueItemResults_price_to_income);
            //System.err.println("timeValueItemResults_mortgage_affordability:" + timeValueItemResults_mortgage_affordability);
            //System.err.println("timeValueItemResults_rent_affordability:" + timeValueItemResults_rent_affordability);

            affordability = new Affordability();
            if (timeValueItemResults_price_to_income != null) {
                affordability.price_to_income = Double.valueOf(timeValueItemResults_price_to_income.get(timeValueItemResults_price_to_income.size() - 1).getValue());
            }
            if (timeValueItemResults_mortgage_affordability != null) {
                affordability.mortgage_affordability = Double.valueOf(timeValueItemResults_mortgage_affordability.get(timeValueItemResults_mortgage_affordability.size() - 1).getValue());
            }
            if (timeValueItemResults_rent_affordability != null) {
                affordability.rent_affordability = Double.valueOf(timeValueItemResults_rent_affordability.get(timeValueItemResults_rent_affordability.size() - 1).getValue());
            }
        }

        model.addAttribute("affordabilityResult", affordability); //购房压力指数
    }

    /**
     * 房租走势
     *
     * @param model
     * @param zipcode
     */
    public void rentByZip(Model model, String zipcode) {

        /*
        List<TimeSeriesItem> items = new ArrayList<>();
        List<TimeSeriesDataAllRentMedian> list = timeSeriesDataAllRentMedianService.findByZipcodeOrderByTimeAsc(zipcode);

        if (list.size() > 0) {
            for (TimeSeriesDataAllRentMedian item : list) {
                TimeSeriesItem timeSeriesItem = new TimeSeriesItem();
                timeSeriesItem.setTime(DateUtils.DateToStr(item.getTime(), "yyyy-MM"));
                timeSeriesItem.setValue(item.getValue());
                items.add(timeSeriesItem);
            }
        }

        if (items != null && items.size() > 60) {
            Collections.reverse(items);
            items = items.subList(0, 60);
            Collections.reverse(items);
        }
        model.addAttribute("RentTrendResult", items); //房租走势
        */
        List<TimeSeriesItem> items = new ArrayList<>();
        String key = "zillow/Zip_ZriPerSqft_AllHomes/" + zipcode + ".json";
        List<TimeValueItemResult> timeValueItemResults = downloadService.downloadTimeValuesFromOSS(key, "5");
        if (timeValueItemResults != null && timeValueItemResults.size() > 0) {
            for (TimeValueItemResult item : timeValueItemResults) {
                TimeSeriesItem timeSeriesItem = new TimeSeriesItem();
                timeSeriesItem.setTime(item.getTime());
                timeSeriesItem.setValue(Double.valueOf(item.getValue()));
                items.add(timeSeriesItem);
            }
        }
        model.addAttribute("RentTrendResult", items); //房租走势
    }

    /**
     * 公寓房价变化(condo房价变化)
     *
     * @param model
     * @param zipcode
     */
    public void condoRentTrendResult(Model model, String zipcode) {

        /*
        List<TimeSeriesDataAllCondos> list = timeSeriesDataAllCondosService.findByZipcodeOrderByTimeAsc(zipcode);

        List<TimeSeriesItem> items = new ArrayList<TimeSeriesItem>();
        for (TimeSeriesDataAllCondos timeSeriesData : list) {
            TimeSeriesItem item = new TimeSeriesItem();
            item.setTime(DateUtils.DateToStr(timeSeriesData.getTime(), "yyyy-MM"));
            item.setValue(timeSeriesData.getValue());
            items.add(item);
        }
        if (items != null && items.size() > 60) {
            Collections.reverse(items);
            items = items.subList(0, 60);
            Collections.reverse(items);
        }
        model.addAttribute("CondoRentTrendResult", items); //condo房价变化

        */

        String time = "5";
        //http://youhome.oss-cn-zhangjiakou.aliyuncs.com/zillow/Zip_Zhvi_Condominum/02563.json
        //http://youhome.oss-cn-zhangjiakou.aliyuncs.com/zillow/Zip_Zhvi_SingleFamilyResidence/02061.json
        String key_Zip_Zhvi_Condominum = "zillow/Zip_Zhvi_Condominum/" + zipcode + ".json";

        List<TimeValueItemResult> results_Zip_Zhvi_Condominum = downloadService.downloadTimeValuesFromOSS(key_Zip_Zhvi_Condominum, time);
        List<TimeSeriesItem> zip_zhvi_condominum = new ArrayList<>();

        if (results_Zip_Zhvi_Condominum != null && results_Zip_Zhvi_Condominum.size() > 0) {
            for (TimeValueItemResult item : results_Zip_Zhvi_Condominum) {
                TimeSeriesItem timeSeriesItem = new TimeSeriesItem();
                timeSeriesItem.setTime(item.getTime());
                timeSeriesItem.setValue(Double.valueOf(item.getValue()));
                zip_zhvi_condominum.add(timeSeriesItem);
            }
        }
        //System.err.println("//condo房价变化:" + zip_zhvi_condominum);
        model.addAttribute("CondoRentTrendResult", zip_zhvi_condominum); //condo房价变化
    }

    /**
     * 独栋别墅(SFR)房价变化
     *
     * @param model
     * @param zipcode
     */
    public void sFRRentTrendResult(Model model, String zipcode) {

        /*
        List<TimeSeriesDataAllSfh> list = timeSeriesDataAllSfhService.findByZipcodeOrderByTimeAsc(zipcode);

        List<TimeSeriesItem> items = new ArrayList<TimeSeriesItem>();

        for (TimeSeriesDataAllSfh timeSeriesData : list) {
            TimeSeriesItem item = new TimeSeriesItem();
            item.setTime(DateUtils.DateToStr(timeSeriesData.getTime(), "yyyy-MM"));
            item.setValue(timeSeriesData.getValue());
            items.add(item);
        }
        if (items != null && items.size() > 60) {
            Collections.reverse(items);
            items = items.subList(0, 60);
            Collections.reverse(items);
        }
        model.addAttribute("SFRRentTrendResult", items); //SFR房价变化

        */

        String time = "5";
        //http://youhome.oss-cn-zhangjiakou.aliyuncs.com/zillow/Zip_Zhvi_SingleFamilyResidence/02061.json
        String key_Zip_Zhvi_SingleFamilyResidence = "zillow/Zip_Zhvi_SingleFamilyResidence/" + zipcode + ".json";
        List<TimeValueItemResult> results_Zip_Zhvi_SingleFamilyResidence = downloadService.downloadTimeValuesFromOSS(key_Zip_Zhvi_SingleFamilyResidence, time);
        List<TimeSeriesItem> zip_zhvi_singlefamilyresidence = new ArrayList<>();

        if (results_Zip_Zhvi_SingleFamilyResidence != null && results_Zip_Zhvi_SingleFamilyResidence.size() > 0) {
            for (TimeValueItemResult item : results_Zip_Zhvi_SingleFamilyResidence) {
                TimeSeriesItem timeSeriesItem = new TimeSeriesItem();
                timeSeriesItem.setTime(item.getTime());
                timeSeriesItem.setValue(Double.valueOf(item.getValue()));
                zip_zhvi_singlefamilyresidence.add(timeSeriesItem);
            }
        }
        //System.err.println("SFRRentTrendResult:" + zip_zhvi_singlefamilyresidence);
        model.addAttribute("SFRRentTrendResult", zip_zhvi_singlefamilyresidence); //SFR房价变化
    }

    /**
     * 房价/租金/回报率
     *
     * @param model
     * @param zipcode
     */
    public void house_Prices_Rents_Rewards(Model model, String zipcode) {

        /*
        List<TimeSeriesDataAllRentByZip> rent_list = timeSeriesDataAllRentByZipService.findByZipcodeOrderByTimeAsc(zipcode);
        List<TimeSeriesDataAllHomes> price_list = timeSeriesDataAllHomesService.findByZipcodeOrderByTimeAsc(zipcode);

        //房价
        List<TimeSeriesItem> rents = new ArrayList<TimeSeriesItem>();
        for (TimeSeriesDataAllRentByZip item : rent_list) {
            TimeSeriesItem timeSeriesItem = new TimeSeriesItem();
            timeSeriesItem.setTime(DateUtils.DateToStr(item.getTime(), "yyyy-MM"));
            timeSeriesItem.setValue(item.getValue());
            rents.add(timeSeriesItem);
        }
        if (rents != null && rents.size() > 60) {
            Collections.reverse(rents);
            rents = rents.subList(0, 60);
            Collections.reverse(rents);
        }
        //租金
        List<TimeSeriesItem> prices = new ArrayList<TimeSeriesItem>();
        for (TimeSeriesDataAllHomes item : price_list) {
            TimeSeriesItem timeSeriesItem = new TimeSeriesItem();
            timeSeriesItem.setTime(DateUtils.DateToStr(item.getTime(), "yyyy-MM"));
            timeSeriesItem.setValue(item.getValue());
            prices.add(timeSeriesItem);
        }
        if (prices != null && prices.size() > 60) {
            Collections.reverse(prices);
            prices = prices.subList(0, 60);
            Collections.reverse(prices);
        }
        //租金回报
        List<TimeSeriesItem> rewards = new ArrayList<TimeSeriesItem>();
        if (rents.size() > 0 && prices.size() > 0) {

            for (int i = 0; i < rents.size(); i++) {
                TimeSeriesItem timeSeriesItem = new TimeSeriesItem();
                timeSeriesItem.setTime(rents.get(i).getTime());
                Double reward = rents.get(i).getValue() * 12 / prices.get(i).getValue() * 100;
                timeSeriesItem.setValue(reward);
                rewards.add(timeSeriesItem);
            }

            for (TimeSeriesItem rent_item : rents) {
                for (TimeSeriesItem price_item : prices) {
                    if (rent_item.getTime().equals(price_item.getTime())) {
                        TimeSeriesItem timeSeriesItem = new TimeSeriesItem();
                        timeSeriesItem.setTime(rent_item.getTime());
                        Double reward = 0.0;
                        Double price = price_item.getValue();
                        if (price != 0) {
                            reward = rent_item.getValue() * 12 / price * 100;
                        }
                        timeSeriesItem.setValue(reward);
                        rewards.add(timeSeriesItem);
                    }
                }
            }
        }

        if (rewards != null && rewards.size() > 60) {
            Collections.reverse(rewards);
            rewards = rewards.subList(0, 60);
            Collections.reverse(rewards);
        }

        model.addAttribute("HousePriceResult", prices); //房价
        model.addAttribute("RentResult", rents); //租金
        model.addAttribute("RentRewardsResult", rewards); //租金回报

        */

        String time = "5"; //5年
        //http://youhome.oss-cn-zhangjiakou.aliyuncs.com/zillow/Zip_Zhvi_AllHomes/02061.json
        String key_Zip_Zhvi_AllHomes = "zillow/Zip_Zhvi_AllHomes/" + zipcode + ".json"; //房价
        String key_Zip_Zri_AllHomesPlusMultifamily = "zillow/Zip_Zri_AllHomesPlusMultifamily/" + zipcode + ".json";  //租金
        List<TimeValueItemResult> timeValueItemResults_Zip_Zhvi_AllHomes = downloadService.downloadTimeValuesFromOSS(key_Zip_Zhvi_AllHomes, time);
        List<TimeValueItemResult> timeValueItemResults_Zip_Zri_AllHomesPlusMultifamily = downloadService.downloadTimeValuesFromOSS(key_Zip_Zri_AllHomesPlusMultifamily, time);

        List<TimeSeriesItem> rent_items = new ArrayList<>(); //租金
        List<TimeSeriesItem> price_items = new ArrayList<>();//房价
        List<TimeSeriesItem> rewards = new ArrayList<>();  //租金回报

        if (timeValueItemResults_Zip_Zhvi_AllHomes != null && timeValueItemResults_Zip_Zhvi_AllHomes.size() > 0) {
            for (TimeValueItemResult timeValueItemResult : timeValueItemResults_Zip_Zhvi_AllHomes) {
                TimeSeriesItem timeSeriesItem = new TimeSeriesItem();
                timeSeriesItem.setTime(timeValueItemResult.getTime());
                timeSeriesItem.setValue(Double.valueOf(timeValueItemResult.getValue()));
                price_items.add(timeSeriesItem);
            }
        }
        if (timeValueItemResults_Zip_Zri_AllHomesPlusMultifamily != null && timeValueItemResults_Zip_Zri_AllHomesPlusMultifamily.size() > 0) {
            for (TimeValueItemResult timeValueItemResult : timeValueItemResults_Zip_Zri_AllHomesPlusMultifamily) {
                TimeSeriesItem timeSeriesItem = new TimeSeriesItem();
                timeSeriesItem.setTime(timeValueItemResult.getTime());
                timeSeriesItem.setValue(Double.valueOf(timeValueItemResult.getValue()));
                rent_items.add(timeSeriesItem);
            }
        }

        if (rent_items.size() > 0 && price_items.size() > 0) {
            for (TimeSeriesItem rent_item : rent_items) {
                for (TimeSeriesItem price_item : price_items) {
                    if (rent_item.getTime().compareTo(price_item.getTime()) == 0) {
                        if (rent_item.getValue() != null && price_item.getValue() != null && price_item.getValue() != 0) {
                            TimeSeriesItem timeSeriesItem = new TimeSeriesItem();
                            timeSeriesItem.setTime(rent_item.getTime());
                            // 租金回报 = 租金 * 12 / 房价 * 100
                            double v = rent_item.getValue() * 12 / price_item.getValue() * 100;
                            timeSeriesItem.setValue(v);
                            rewards.add(timeSeriesItem);
                        }
                        break;
                    }

                }
            }
        }

        model.addAttribute("HousePriceResult", price_items); //房价
        model.addAttribute("RentResult", rent_items); //租金
        model.addAttribute("RentRewardsResult", rewards); //租金回报
    }

    /**
     * state/US房价变化
     *
     * @param model
     * @param zipcode
     */
    public void stateUS(Model model, String zipcode) {

        /*
        System.err.println("zipcode============>>" + zipcode);
        Zip zip = zipService.selectByPrimaryKey(zipcode);
        System.err.println(zip.toString());

        List<TimeSeriesItem> state_items = new ArrayList<>();
        List<TimeSeriesItem> us_items = new ArrayList<>();
        if (zip != null) {

            String state = zip.getState();
            String metro = zip.getMetro();

            if (state.length() < 3) {
                state = StateUtils.convert(state);
            }
            System.err.println("metro======:" + metro);
            System.err.println("state=======:" + state);

            if (!StringUtils.isEmpty(state)) {
                List<TimeSeriesDataAllHomesByState> state_list = timeSeriesDataAllHomesByStateService.findByStateLikeOrderByTimeAsc(state);


                if (state_list != null && state_list.size() > 0) {
                    for (TimeSeriesDataAllHomesByState item : state_list) {
                        TimeSeriesItem timeSeriesItem = new TimeSeriesItem();
                        timeSeriesItem.setTime(DateUtils.DateToStr(item.getTime(), "yyyy-MM"));
                        timeSeriesItem.setValue(item.getValue());
                        state_items.add(timeSeriesItem);
                    }
                }
                if (state_items != null && state_items.size() > 60) {
                    Collections.reverse(state_items);
                    state_items = state_items.subList(0, 60);
                    Collections.reverse(state_items);
                }
            }
            if (!StringUtils.isEmpty(metro)) {
                List<TimeSeriesDataAllHomesByMetro> us_list = timeSeriesDataAllHomesByMetroService.findByMetroLikeOrderByTimeAsc(metro);

                if (us_list != null && us_list.size() > 0) {
                    for (TimeSeriesDataAllHomesByMetro item : us_list) {
                        TimeSeriesItem timeSeriesItem = new TimeSeriesItem();
                        timeSeriesItem.setTime(DateUtils.DateToStr(item.getTime(), "yyyy-MM"));
                        timeSeriesItem.setValue(item.getValue());
                        us_items.add(timeSeriesItem);
                    }
                }
                if (us_items != null && us_items.size() > 60) {
                    Collections.reverse(us_items);
                    us_items = us_items.subList(0, 60);
                    Collections.reverse(us_items);
                }
            }
        }
        model.addAttribute("StateHousePriceResult", state_items); //本州房价
        model.addAttribute("USHousePriceResult", us_items); //美国房价

        */

        Zip zip = zipService.selectByPrimaryKey(zipcode);
        if (zip != null) {
            String state = zip.getState();
            String metro = zip.getMetro();
            if (!StringUtils.isEmpty(state) && state.length() < 3) {
                state = StateUtils.convert(state);
            }
            String time = "5";
            //http://youhome.oss-cn-zhangjiakou.aliyuncs.com/zillow/State_Zhvi_AllHomes/missouri.json
            //http://youhome.oss-cn-zhangjiakou.aliyuncs.com/zillow/Metro_Zhvi_AllHomes/fond_du_lac_wi.json

            List<TimeSeriesItem> items_metro = new ArrayList<>();
            if (!StringUtils.isEmpty(metro)) {
                String key_metro = "zillow/Metro_Zhvi_AllHomes/" + StringUtil.replaceBlankAndComma(metro) + ".json";
                List<TimeValueItemResult> results_metro = downloadService.downloadTimeValuesFromOSS(key_metro, time);
                if (results_metro != null && results_metro.size() > 0) {
                    for (TimeValueItemResult item : results_metro) {
                        TimeSeriesItem timeSeriesItem = new TimeSeriesItem();
                        timeSeriesItem.setTime(item.getTime());
                        timeSeriesItem.setValue(Double.valueOf(item.getValue()));
                        items_metro.add(timeSeriesItem);
                    }
                }
            }

            model.addAttribute("USHousePriceResult", items_metro); //美国房价

            List<TimeSeriesItem> items_state = new ArrayList<>();
            if (!StringUtils.isEmpty(state)) {
                String key_state = "zillow/State_Zhvi_AllHomes/" + state.toLowerCase() + ".json";
                List<TimeValueItemResult> results_state = downloadService.downloadTimeValuesFromOSS(key_state, time);
                if (results_state != null && results_state.size() > 0) {
                    for (TimeValueItemResult item : results_state) {
                        TimeSeriesItem timeSeriesItem = new TimeSeriesItem();
                        timeSeriesItem.setTime(item.getTime());
                        timeSeriesItem.setValue(Double.valueOf(item.getValue()));
                        items_state.add(timeSeriesItem);
                    }
                }
            }
            //System.err.println("StateHousePriceResult:" + items_state);
            model.addAttribute("StateHousePriceResult", items_state); //本州房价
        }

    }

    /**
     * 房源周边景点
     *
     * @param model
     */
    public void poi(Model model, ListHub listHub) {

        long time = System.currentTimeMillis();

        List<InterestPointResult> interestPointResults = new ArrayList<>();
        List<String> markers = new ArrayList<>();
        if (listHub != null) {
            Double lat = listHub.getLatitude(); //纬度
            Double lng = listHub.getLongitude(); //经度

            double distance = 1; //距离(千米)
            if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                interestPointResults = solrService.selectPoiByCoordinateAndDist(lat, lng, distance, 1000);
                //interestPointResults = density(interestPointResults,10);
                //interestPointResults = density(interestPointResults,20);
                //interestPointResults = density(interestPointResults,30);
                interestPointResults = density(interestPointResults, 40);
                System.err.println("interestPointResults====11=====size=======>>" + interestPointResults.size());
                if (interestPointResults != null && interestPointResults.size() > 0) {
                    interestPointResults = removeHouseRoundByRadius(lat, lng, 30, 260, interestPointResults);
                }
                System.err.println("interestPointResults====22=====size=======>>" + interestPointResults.size());
                String marker = "markers=icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/house.png|" + lat + "," + lng;
                markers.add(marker);
            } else {
                String marker = "markers=icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/house.png|" + listHub.getAddress();
                markers.add(marker);
            }
        }
        if (interestPointResults != null && interestPointResults.size() > 0)
            markers.add(sortOut(interestPointResults));
//        for (InterestPointResult pointResult : interestPointResults) {
//            //System.err.println(pointResult.toString());
//            Set<String> categories = pointResult.getCategories();
//            String color = setPoiColor(categories);
//            String marker = "markers=size:mid|color:" + color + "|" + pointResult.getLatitude() + "," + pointResult.getLongitude();
//            markers.add(marker);
//        }

        String center = null;
        if (!StringUtils.isEmpty(listHub.getLatitude()) && !StringUtils.isEmpty(listHub.getLongitude())) {
            center = listHub.getLatitude() + "," + listHub.getLongitude();
        }

        //url 最大长度  8192
        String map = "https://maps.google.cn/maps/api/staticmap?center=" + center + "&zoom=16&size=640x640&key=AIzaSyC-a-6fOuFPRnyCLbAuCn-ptFttkavNkvw&style=feature:poi|visibility:off&" + String.join("&", markers);
        //String map = "https://maps.google.cn/maps/api/staticmap?center=" + center + "&zoom=18&size=640x640&key=AIzaSyDH6NBqY397pB_dQfDyb4jLwVD73FeOELU&" + sortOut(interestPointResults);
        model.addAttribute("POIShortResult", map);
        //System.err.println("poi:====>>" + map);
        //System.err.println("time:" + (System.currentTimeMillis() - time));

    }

    /**
     * 房源周边景点  坐标
     *
     * @param model
     * @param listHub
     */
    public void poi2(Model model, ListHub listHub) {
        long time = System.currentTimeMillis();
        POIShortResult poi_coordinates_result = new POIShortResult();

        if (listHub != null) {
            Double lat = listHub.getLatitude(); //纬度
            Double lng = listHub.getLongitude(); //经度
            //System.err.println("POI===" + lat + "==" + lng);
            double distance = 0.5; //距离(千米)
            if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                HousePoint point = new HousePoint(lat, lng);
                poi_coordinates_result.setHouse(point);

                List<InterestPointResult> interestPointResults = solrService.selectPoiByCoordinateAndDist(lat, lng, distance, 1000);
                interestPointResults = density(interestPointResults, 10);
                //System.err.println("interestPointResults====11=====size=======>>" + interestPointResults.size());
                if (interestPointResults != null && interestPointResults.size() > 0) {
                    interestPointResults = removeHouseRoundByRadius(lat, lng, 30, 10000, interestPointResults);
                }
                //System.err.println("interestPointResults====22=====size=======>>" + interestPointResults.size());
                List<InterestPointShortResult> list = new ArrayList<>();
                if (interestPointResults != null && interestPointResults.size() > 0) {
                    for (InterestPointResult interestPointResult : interestPointResults) {
                        InterestPointShortResult interestPointShortResult = new InterestPointShortResult();
                        interestPointShortResult.setLat(interestPointResult.getLatitude());
                        interestPointShortResult.setLng(interestPointResult.getLongitude());
                        interestPointShortResult.setCates(interestPointResult.getCategories());
                        list.add(interestPointShortResult);
                    }
                    poi_coordinates_result.setList(list);
                }
            }
        }

        System.err.println("time:" + (System.currentTimeMillis() - time));
        //System.err.println("poi_coordinates_result:" + poi_coordinates_result);
        model.addAttribute("poi_coordinates_result", poi_coordinates_result);
    }

    public List<InterestPointResult> density(List<InterestPointResult> list, int dist) {
        List<InterestPointResult> rows = new ArrayList<>();
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                if (i == 0) {
                    rows.add(list.get(i));
                } else {
                    Boolean flag = true;
                    Double lat = list.get(i).getLatitude();
                    Double lng = list.get(i).getLongitude();
                    for (InterestPointResult item : rows) {

                        Double lat2 = item.getLatitude();
                        Double lng2 = item.getLongitude();
                        double distance = GoogleMapUtils.getDistance(lat, lng, lat2, lng2);

                        //System.err.println("lat:"+lat+"===>>lng:"+lng+"===>>lat2:"+lat2+"====>>lng2:"+lng2);
                        //System.err.println("distance:"+distance);
                        if (distance < dist) {
                            flag = false;
                            break;
                        }
                    }

                    if (flag) {
                        rows.add(list.get(i));
                    }
                }
            }
        }
        return rows;
    }

    private String sortOut(List<InterestPointResult> interestPointResults) {
        List<String> markers = new ArrayList<>();

        List<String> markers_Arts_Entertainment = new ArrayList<>(); //娱乐 1
        markers_Arts_Entertainment.add("size:tiny");
//      markers_Arts_Entertainment.add("color:0xff0000");
        markers_Arts_Entertainment.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p1.png");

        List<String> markers_Automotive = new ArrayList<>(); //汽车 2
        markers_Automotive.add("size:tiny");
//      markers_Automotive.add("color:0xffff00");
        markers_Automotive.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p2.png");

        List<String> markers_Beauty = new ArrayList<>();//美容 3
        markers_Beauty.add("size:tiny");
//        markers_Beauty.add("color:0x00ff00");
        markers_Beauty.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p3.png");

        List<String> markers_Education = new ArrayList<>(); //教育 4
        markers_Education.add("size:tiny");
        //markers_Education.add("color:0x00ffff");
        markers_Education.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p4.png");

        List<String> markers_Event_Planning_Services = new ArrayList<>(); //服务 5
        markers_Event_Planning_Services.add("size:tiny");
        //markers_Event_Planning_Services.add("color:0x0000ff");
        markers_Event_Planning_Services.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p5.png");

        List<String> markers_Financial_Services = new ArrayList<>(); //金融 6
        markers_Financial_Services.add("size:tiny");
        //markers_Financial_Services.add("color:0xff00ff");
        markers_Financial_Services.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p6.png");

        List<String> markers_Food = new ArrayList<>();//食品 7
        markers_Food.add("size:tiny");
        //markers_Food.add("color:0x808080");
        markers_Food.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p7.png");

        List<String> markers_Health_Medical = new ArrayList<>();//健康 8
        markers_Health_Medical.add("size:tiny");
        //markers_Health_Medical.add("color:0x008000");
        markers_Health_Medical.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p8.png");

        List<String> markers_Home_Services = new ArrayList<>();//家政 9
        markers_Home_Services.add("size:tiny");
        //markers_Home_Services.add("color:0x800000");
        markers_Home_Services.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p9.png");

        List<String> markers_Hotels_Travel = new ArrayList<>();//酒店 10
        markers_Hotels_Travel.add("size:tiny");
        //markers_Hotels_Travel.add("color:0x000080");
        markers_Hotels_Travel.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p10.png");

        List<String> markers_Local_Events_Flavor = new ArrayList<>();//本地生活 11
        markers_Local_Events_Flavor.add("size:tiny");
        //markers_Local_Events_Flavor.add("color:0x808000");
        markers_Local_Events_Flavor.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p11.png");

        List<String> markers_Local_Media = new ArrayList<>();//本地媒体 12
        markers_Local_Media.add("size:tiny");
        //markers_Local_Media.add("color:0x800080");
        markers_Local_Media.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p12.png");

        List<String> markers_Local_Services = new ArrayList<>();//本地服务 13
        markers_Local_Services.add("size:tiny");
        //markers_Local_Services.add("color:0xc0c0c0");
        markers_Local_Services.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p13.png");

        List<String> markers_Nightlife = new ArrayList<>();//夜生活 14
        markers_Nightlife.add("size:tiny");
        //markers_Nightlife.add("color:0x008080");
        markers_Nightlife.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p14.png");

        List<String> markers_Pets = new ArrayList<>();//宠物 15
        markers_Pets.add("size:tiny");
        //markers_Pets.add("color:0x2f4f4f");
        markers_Pets.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p15.png");

        List<String> markers_Professional_Services = new ArrayList<>();//专业服务 16
        markers_Professional_Services.add("size:tiny");
        //markers_Professional_Services.add("color:0x483d8b");
        markers_Professional_Services.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p16.png");

        List<String> markers_Public_Services_Government = new ArrayList<>(); //政府 17
        markers_Public_Services_Government.add("size:tiny");
        //markers_Public_Services_Government.add("color:0xff4500");
        markers_Public_Services_Government.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p17.png");

        List<String> markers_Real_Estate = new ArrayList<>();//房地产 18
        markers_Real_Estate.add("size:tiny");
        // markers_Real_Estate.add("color:0xff8c00");
        markers_Real_Estate.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p18.png");

        List<String> markers_Recreation = new ArrayList<>();//户外 19
        markers_Recreation.add("size:tiny");
        //markers_Recreation.add("color:0x9932cc");
        markers_Recreation.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p19.png");

        List<String> markers_Religious_Organizations = new ArrayList<>();//宗教 20
        markers_Religious_Organizations.add("size:tiny");
        //markers_Religious_Organizations.add("color:0x3cb371");
        markers_Religious_Organizations.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p20.png");

        List<String> markers_Restaurants = new ArrayList<>(); //餐馆 21
        markers_Restaurants.add("size:tiny");
        //markers_Restaurants.add("color:0x3cb371");
        markers_Restaurants.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p21.png");

        List<String> markers_Shopping = new ArrayList<>(); //购物 22
        markers_Shopping.add("size:tiny");
        //markers_Shopping.add("color:0x008b8b");
        markers_Shopping.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p22.png");

        List<String> markers_Travel = new ArrayList<>();//旅游 23
        markers_Travel.add("size:tiny");
        //markers_Travel.add("color:0xf4a460");
        markers_Travel.add("icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/p23.png");

        for (InterestPointResult pointResult : interestPointResults) {
            Double lat = pointResult.getLatitude();
            Double lng = pointResult.getLongitude();
            Set<String> categories = pointResult.getCategories();
            if (categories.contains("Arts & Entertainment")) { //娱乐
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Arts_Entertainment.add(lat + "," + lng);
                }
            }
            if (categories.contains("Automotive")) { //汽车
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Automotive.add(lat + "," + lng);
                }
            }
            if (categories.contains("Beauty")) { //美容
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Beauty.add(lat + "," + lng);
                }
            }
            if (categories.contains("Education")) { //教育
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Education.add(lat + "," + lng);
                }
            }
            if (categories.contains("Event Planning & Services")) { //服务
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Education.add(lat + "," + lng);
                }
            }
            if (categories.contains("Financial Services")) {//金融
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Financial_Services.add(lat + "," + lng);
                }
            }
            if (categories.contains("Food")) {//食品
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Food.add(lat + "," + lng);
                }
            }
            if (categories.contains("Health & Medical")) { //健康
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Health_Medical.add(lat + "," + lng);
                }
            }
            if (categories.contains("Home Services")) {//家政
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Home_Services.add(lat + "," + lng);
                }
            }
            if (categories.contains("Hotels & Travel")) { //酒店
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Hotels_Travel.add(lat + "," + lng);
                }
            }
            if (categories.contains("Local Events & Flavor")) { //本地生活
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Local_Events_Flavor.add(lat + "," + lng);
                }
            }
            if (categories.contains("Local Media")) { //本地媒体
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Local_Media.add(lat + "," + lng);
                }
            }
            if (categories.contains("Local Services")) { //本地服务
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Local_Services.add(lat + "," + lng);
                }
            }
            if (categories.contains("Nightlife")) { //夜生活
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Nightlife.add(lat + "," + lng);
                }
            }
            if (categories.contains("Pets")) {  //宠物
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Pets.add(lat + "," + lng);
                }
            }
            if (categories.contains("Professional Services")) { //专业服务
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Professional_Services.add(lat + "," + lng);
                }
            }
            if (categories.contains("Public Services & Government")) {  //政府
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Public_Services_Government.add(lat + "," + lng);
                }
            }
            if (categories.contains("Real Estate")) {  //房地产
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Real_Estate.add(lat + "," + lng);
                }
            }
            if (categories.contains("Recreation")) {  //户外
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Recreation.add(lat + "," + lng);
                }
            }
            if (categories.contains("Religious Organizations")) { //宗教
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Religious_Organizations.add(lat + "," + lng);
                }
            }
            if (categories.contains("Restaurants")) { //餐馆
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Restaurants.add(lat + "," + lng);
                }
            }
            if (categories.contains("Shopping")) { //购物
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Shopping.add(lat + "," + lng);
                }
            }
            if (categories.contains("Travel")) {//旅游
                if (!StringUtils.isEmpty(lat) && !StringUtils.isEmpty(lng)) {
                    markers_Travel.add(lat + "," + lng);
                }
            }
        }

        if (markers_Arts_Entertainment.size() > 2)
            markers.add("markers=" + String.join("|", markers_Arts_Entertainment));
        if (markers_Automotive.size() > 2) markers.add("markers=" + String.join("|", markers_Automotive));
        if (markers_Beauty.size() > 2) markers.add("markers=" + String.join("|", markers_Beauty));
        if (markers_Education.size() > 2) markers.add("markers=" + String.join("|", markers_Education));
        if (markers_Event_Planning_Services.size() > 2)
            markers.add("markers=" + String.join("|", markers_Event_Planning_Services));
        if (markers_Financial_Services.size() > 2)
            markers.add("markers=" + String.join("|", markers_Financial_Services));
        if (markers_Food.size() > 2) markers.add("markers=" + String.join("|", markers_Food));
        if (markers_Health_Medical.size() > 2) markers.add("markers=" + String.join("|", markers_Health_Medical));
        if (markers_Home_Services.size() > 2) markers.add("markers=" + String.join("|", markers_Home_Services));
        if (markers_Hotels_Travel.size() > 2) markers.add("markers=" + String.join("|", markers_Hotels_Travel));
        if (markers_Local_Events_Flavor.size() > 2)
            markers.add("markers=" + String.join("|", markers_Local_Events_Flavor));
        if (markers_Local_Media.size() > 2) markers.add("markers=" + String.join("|", markers_Local_Media));
        if (markers_Local_Services.size() > 2) markers.add("markers=" + String.join("|", markers_Local_Services));
        if (markers_Nightlife.size() > 2) markers.add("markers=" + String.join("|", markers_Nightlife));
        if (markers_Pets.size() > 2) markers.add("markers=" + String.join("|", markers_Pets));
        if (markers_Professional_Services.size() > 2)
            markers.add("markers=" + String.join("|", markers_Professional_Services));
        if (markers_Public_Services_Government.size() > 2)
            markers.add("markers=" + String.join("|", markers_Public_Services_Government));
        if (markers_Real_Estate.size() > 2) markers.add("markers=" + String.join("|", markers_Real_Estate));
        if (markers_Recreation.size() > 2) markers.add("markers=" + String.join("|", markers_Recreation));
        if (markers_Religious_Organizations.size() > 2)
            markers.add("markers=" + String.join("|", markers_Religious_Organizations));
        if (markers_Restaurants.size() > 2) markers.add("markers=" + String.join("|", markers_Restaurants));
        if (markers_Shopping.size() > 2) markers.add("markers=" + String.join("|", markers_Shopping));
        if (markers_Travel.size() > 2) markers.add("markers=" + String.join("|", markers_Travel));

        return String.join("&", markers);
    }

    private String setPoiColor(Set<String> categories) {
        if (categories.contains("Arts & Entertainment")) return "0xff0000";
        if (categories.contains("Automotive")) return "0xffff00";  //汽车
        if (categories.contains("Beauty")) return "0x00ff00"; //美容
        if (categories.contains("Education")) return "0x00ffff"; //教育
        if (categories.contains("Event Planning & Services")) return "0x0000ff"; //服务
        if (categories.contains("Financial Services")) return "0xff00ff";//金融
        if (categories.contains("Food")) return "0x808080"; //食品
        if (categories.contains("Health & Medical")) return "0x008000"; //健康
        if (categories.contains("Home Services")) return "0x800000"; //家政
        if (categories.contains("Hotels & Travel")) return "0x000080"; //酒店
        if (categories.contains("Local Events & Flavor")) return "0x808000"; //本地生活
        if (categories.contains("Local Media")) return "0x800080"; //本地媒体
        if (categories.contains("Local Services")) return "0xc0c0c0"; //本地服务
        if (categories.contains("Nightlife")) return "0x008080"; //夜生活
        if (categories.contains("Pets")) return "0x2f4f4f";  //宠物
        if (categories.contains("Professional Services")) return "0x483d8b"; //专业服务
        if (categories.contains("Public Services & Government")) return "0xff4500";  //政府
        if (categories.contains("Real Estate")) return "0xff8c00";  //房地产
        if (categories.contains("Recreation")) return "0x9932cc";  //户外
        if (categories.contains("Religious Organizations")) return "0xadff2f"; //宗教
        if (categories.contains("Restaurants")) return "0x3cb371";  //餐馆
        if (categories.contains("Shopping")) return "0x008b8b"; //购物
        if (categories.contains("Travel")) return "0xf4a460";  //旅游

        return null;
    }

    /**
     * 删除以房源为中心点抒写半径内的POI坐标点
     *
     * @param lat
     * @param lng
     * @param radius
     * @param interestPointResults
     * @return
     */
    private List<InterestPointResult> removeHouseRoundByRadius(Double lat, Double lng, Integer radius, Integer row, List<InterestPointResult> interestPointResults) {
        if (StringUtils.isEmpty(lat) || StringUtils.isEmpty(lng)) {
            return null;
        }
        List<InterestPointResult> items = new ArrayList<>();
        for (InterestPointResult pointResult : interestPointResults) {
            if (!StringUtils.isEmpty(pointResult.getLatitude()) && !StringUtils.isEmpty(pointResult.getLongitude())) {
                double distance = LocationUtils.getDistance(lng, lat, pointResult.getLongitude(), pointResult.getLatitude());
                // System.err.println("lat:" + lat + " lng:" + lng + " lat1:" + pointResult.getLatitude() + " lng1:" + pointResult.getLongitude() + "distance:" + distance + "<<====>>" + pointResult.getDist());
                if (distance > radius) {
                    items.add(pointResult);
                }
            }
        }
        if (items != null && items.size() > row && row > 0) {
            items = items.subList(0, row);
        }
        return items;
    }

    /**
     * 房源学区
     *
     * @param model
     * @param listHub
     */
    public void schoolPolygon(Model model, ListHub listHub, com.youhome.service.result.School school) {

        String googleStaticMapRootUrl = "https://maps.google.cn/maps/api/staticmap"; // google static map 服务地址
        //String googleKey = "AIzaSyDH6NBqY397pB_dQfDyb4jLwVD73FeOELU"; //google key
        String googleKey = "AIzaSyC-a-6fOuFPRnyCLbAuCn-ptFttkavNkvw"; //google key
        String map_center_point = null; //(房源)地图中心点
        if (!StringUtils.isEmpty(listHub.getLatitude()) && !StringUtils.isEmpty(listHub.getLongitude())) {
            map_center_point = listHub.getLatitude() + "," + listHub.getLongitude();
        }

        List<SchoolItem> elementary = school.getElementary(); //小学
        List<SchoolItem> middle = school.getMiddle(); //初中
        List<SchoolItem> high = school.getHigh(); // 高中

        List<Point> all_schools_points = new ArrayList<>(); //本zip所有学校坐标点
        List<String> all_school_polygon = new ArrayList<>(); //所有学校包含房源的范围

        List<String> elementary_school_polygon = new ArrayList<>();
        List<String> middle_school_polygon = new ArrayList<>();
        List<String> high_school_polygon = new ArrayList<>();

        //房源标记点
        String house_marker = "&markers=icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/house.png|" + map_center_point;
        List<String> elementary_marks = new ArrayList<>();
        List<String> middle_marks = new ArrayList<>();
        List<String> high_marks = new ArrayList<>();
        if (elementary != null && elementary.size() > 0) {
            for (SchoolItem item : elementary) {
                ///System.err.println(item.toString());
                if (!StringUtils.isEmpty(item.getLatitude()) && !StringUtils.isEmpty(item.getLongitude())) {
                    all_schools_points.add(new Point(item.getLatitude(), item.getLongitude()));
                    elementary_marks.add(item.getLatitude() + "," + item.getLongitude());
                }
                //System.err.println("school_id:" + item.getId() + "===elementary==>>" + item.getGrade());
                List<String> jx = analysisSchoolGeometries(listHub, item);
                elementary_school_polygon.addAll(jx);
                all_school_polygon.addAll(jx);
            }
        }
        //System.err.println("----------------------------------elementary----------------------------------------");
        if (middle != null && middle.size() > 0) {
            for (SchoolItem item : middle) {
                if (!StringUtils.isEmpty(item.getLatitude()) && !StringUtils.isEmpty(item.getLongitude())) {
                    all_schools_points.add(new Point(item.getLatitude(), item.getLongitude()));
                    middle_marks.add(item.getLatitude() + "," + item.getLongitude());
                }
                // System.err.println("school_id:" + item.getId() + "===middle==>>" + item.getGrade());
                List<String> jx = analysisSchoolGeometries(listHub, item);
                middle_school_polygon.addAll(jx);
                all_school_polygon.addAll(jx);
            }
        }
        //System.err.println("----------------------------------middle----------------------------------------");
        if (high != null && high.size() > 0) {
            for (SchoolItem item : elementary) {
                if (!StringUtils.isEmpty(item.getLatitude()) && !StringUtils.isEmpty(item.getLongitude())) {
                    all_schools_points.add(new Point(item.getLatitude(), item.getLongitude()));
                    high_marks.add(item.getLatitude() + "," + item.getLongitude());
                }
                //System.err.println("school_id:" + item.getId() + "===high==>>" + item.getGrade());
                List<String> jx = analysisSchoolGeometries(listHub, item);
                high_school_polygon.addAll(jx);
                all_school_polygon.addAll(jx);
            }
        }
        //System.err.println("----------------------------------high----------------------------------------");


        String map = "https://maps.google.cn/maps/api/staticmap?center=" + map_center_point + "&zoom=&size=640x640&scale=1&maptype=roadmap&key=" + googleKey + "&" + house_marker + "&" +
                String.join("&", all_school_polygon);
        List<String> school_markers = new ArrayList<>();
        //System.err.println("schools_points.size:" + all_schools_points.size());
        for (Point point : all_schools_points) {
            if (!StringUtils.isEmpty(point.getLat()) && !StringUtils.isEmpty(point.getLng())) {
                String school_marker = "markers=" + point.getLat() + "," + point.getLng();
                school_markers.add(school_marker);
            }
        }

        String school_marks_string = googleStaticMapRootUrl + "?center=" + map_center_point + "&zoom=&size=640x640&scale=1&maptype=roadmap&key=" + googleKey + "&" + house_marker + "&";
        if (elementary_marks != null && elementary_marks.size() > 0) {
            String elementary_marks_string = "&markers=size:tiny|icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/primary_school.png|" + String.join("|", elementary_marks);
            school_marks_string = school_marks_string + elementary_marks_string;
        }

        if (middle_marks != null && middle_marks.size() > 0) {
            String middle_marks_string = "&markers=size:tiny|icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/middle_school.png|" + String.join("|", middle_marks);
            school_marks_string = school_marks_string + middle_marks_string;
        }

        if (high_marks != null && high_marks.size() > 0) {
            String high_marks_string = "&markers=size:tiny|icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/university.png|" + String.join("|", high_marks);
            school_marks_string = school_marks_string + high_marks_string;
        }


        //学校坐标
        String school_marker_google_static_map = null;

        /*
        if (!school_markers.isEmpty()) {
            String map_school_marker = googleStaticMapRootUrl + "?center=" + map_center_point + "&zoom=&size=640x640&scale=1&maptype=roadmap&key=" + googleKey + "&" + house_marker + "&" + String.join("&", school_markers);
            System.err.println("map_school_marker:" + map_school_marker);
            school_marker_google_static_map = downloadService.downloadFromGoogleStaticMap(map_school_marker);
            System.err.println("SchoolMarkerResult:" + school_marker_google_static_map);
        }

        */
        //System.err.println("school_marks_string:" + school_marks_string);
        school_marker_google_static_map = downloadService.downloadFromGoogleStaticMap(school_marks_string);
        //System.err.println("SchoolMarkerResult:" + school_marker_google_static_map);
        //小学范围
        String elementary_school_polygon_map = null;
        if (!elementary_school_polygon.isEmpty()) {
            String map_elementary_school_polygon = googleStaticMapRootUrl + "?center=" + map_center_point + "&zoom=&size=640x640&scale=1&maptype=roadmap&key=" + googleKey + "&" + house_marker + "&" + String.join("&", elementary_school_polygon);
            //System.err.println("elementary_school_polygon:" + elementary_school_polygon);
            //System.err.println("map_elementary_school_polygon:" + map_elementary_school_polygon);
            elementary_school_polygon_map = downloadService.downloadFromGoogleStaticMap(map_elementary_school_polygon);
        }

        //初中范围
        String middle_school_polygon_map = null;
        if (!middle_school_polygon.isEmpty()) {
            String map_middle_school_polygon = googleStaticMapRootUrl + "?center=" + map_center_point + "&zoom=&size=640x640&scale=1&maptype=roadmap&key=" + googleKey + "&" + house_marker + "&" + String.join("&", middle_school_polygon);
            //System.err.println("map_middle_school_polygon:" + map_middle_school_polygon);
            //System.err.println("downloadService:" + downloadService);
            middle_school_polygon_map = downloadService.downloadFromGoogleStaticMap(map_middle_school_polygon);
        }

        //高中范围
        String high_school_polygon_map = null;
        if (!high_school_polygon.isEmpty()) {
            String map_high_school_polygon = googleStaticMapRootUrl + "?center=" + map_center_point + "&zoom=&size=640x640&scale=1&maptype=roadmap&key=" + googleKey + "&" + house_marker + "&" + String.join("&", high_school_polygon);
            //System.err.println("map_high_school_polygon:" + map_high_school_polygon);
            //System.err.println("high_school_polygon:" + high_school_polygon);
            high_school_polygon_map = downloadService.downloadFromGoogleStaticMap(map_high_school_polygon);
        }

        //所有学校范围图
        System.err.println("SchoolPolygonResult:" + map);
        model.addAttribute("SchoolPolygonResult", map);
        //学校坐标图
        System.err.println("SchoolMarkerResult:" + school_marker_google_static_map);
        model.addAttribute("SchoolMarkerResult", school_marker_google_static_map);
        //小学范围图
        System.err.println("elementary_school_polygon_map:" + elementary_school_polygon_map);
        model.addAttribute("elementary_school_polygon_map", elementary_school_polygon_map);
        //初中范围图
        System.err.println("middle_school_polygon_map:" + middle_school_polygon_map);
        model.addAttribute("middle_school_polygon_map", middle_school_polygon_map);
        //高中范围图
        System.err.println("high_school_polygon_map:" + high_school_polygon_map);
        model.addAttribute("high_school_polygon_map", high_school_polygon_map);
    }


    /**
     * 学校覆盖图 google static map
     *
     * @param model
     * @param listHub
     */
    public void school_polygon(Model model, ListHub listHub, com.youhome.service.result.School school) {

        String googleStaticMapRootUrl = "https://maps.google.cn/maps/api/staticmap"; // google static map 服务地址
        //String googleKey = "AIzaSyDH6NBqY397pB_dQfDyb4jLwVD73FeOELU"; //google key
        String googleKey = "AIzaSyC-a-6fOuFPRnyCLbAuCn-ptFttkavNkvw"; //google key
        String house_point = null; //(房源)地图中心点
        if (!StringUtils.isEmpty(listHub.getLatitude()) && !StringUtils.isEmpty(listHub.getLongitude())) {
            house_point = listHub.getLatitude() + "," + listHub.getLongitude();
        }

        List<SchoolItem> elementary = school.getElementary(); //小学
        List<SchoolItem> middle = school.getMiddle(); //初中
        List<SchoolItem> high = school.getHigh(); // 高中

        List<Point> all_schools_points = new ArrayList<>(); //本zip所有学校坐标点
        List<String> all_school_polygon = new ArrayList<>(); //所有学校包含房源的范围

        List<String> elementary_school_polygon = new ArrayList<>();
        List<String> middle_school_polygon = new ArrayList<>();
        List<String> high_school_polygon = new ArrayList<>();

        //房源标记点
        String house_marker = "&markers=icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/house.png|" + house_point;

        if (elementary != null && elementary.size() > 0) {
            for (SchoolItem item : elementary) {
                if (!StringUtils.isEmpty(item.getLatitude()) && !StringUtils.isEmpty(item.getLongitude())) {
                    all_schools_points.add(new Point(item.getLatitude(), item.getLongitude()));
                }
                List<String> jx = analysisSchoolGeometries(listHub, item);
                if (jx != null && jx.size() > 0) {
                    elementary_school_polygon.addAll(jx);
                    all_school_polygon.addAll(jx);
                }
            }
        }
        if (middle != null && middle.size() > 0) {
            for (SchoolItem item : middle) {
                if (!StringUtils.isEmpty(item.getLatitude()) && !StringUtils.isEmpty(item.getLongitude())) {
                    all_schools_points.add(new Point(item.getLatitude(), item.getLongitude()));
                }
                List<String> jx = analysisSchoolGeometries(listHub, item);
                if (jx != null && jx.size() > 0) {
                    middle_school_polygon.addAll(jx);
                    all_school_polygon.addAll(jx);
                }
            }
        }
        if (high != null && high.size() > 0) {
            for (SchoolItem item : high) {
                if (!StringUtils.isEmpty(item.getLatitude()) && !StringUtils.isEmpty(item.getLongitude())) {
                    all_schools_points.add(new Point(item.getLatitude(), item.getLongitude()));
                }
                List<String> jx = analysisSchoolGeometries(listHub, item);
                if (jx != null && jx.size() > 0) {
                    high_school_polygon.addAll(jx);
                    all_school_polygon.addAll(jx);
                }
            }
        }


        String school_polygon_result = null;
        if (all_school_polygon != null && all_school_polygon.size() > 0) {
            school_polygon_result = googleStaticMapRootUrl + "?center=" + house_point + "&zoom=&size=640x640&scale=1&maptype=roadmap&key=" + googleKey + "&" + house_marker + "&" + String.join("&", all_school_polygon);
        }

        //小学范围
        String elementary_school_polygon_result = null;
        if (!elementary_school_polygon.isEmpty()) {
            String map_elementary_school_polygon = googleStaticMapRootUrl + "?center=" + house_point + "&zoom=&size=640x640&scale=1&maptype=roadmap&key=" + googleKey + "&" + house_marker + "&" + String.join("&", elementary_school_polygon);
            elementary_school_polygon_result = downloadService.downloadFromGoogleStaticMap(map_elementary_school_polygon);
        }

        //初中范围
        String middle_school_polygon_result = null;
        if (!middle_school_polygon.isEmpty()) {
            String map_middle_school_polygon = googleStaticMapRootUrl + "?center=" + house_point + "&zoom=&size=640x640&scale=1&maptype=roadmap&key=" + googleKey + "&" + house_marker + "&" + String.join("&", middle_school_polygon);
            middle_school_polygon_result = downloadService.downloadFromGoogleStaticMap(map_middle_school_polygon);
        }

        //高中范围
        String high_school_polygon_result = null;
        if (!high_school_polygon.isEmpty()) {
            String map_high_school_polygon = googleStaticMapRootUrl + "?center=" + house_point + "&zoom=&size=640x640&scale=1&maptype=roadmap&key=" + googleKey + "&" + house_marker + "&" + String.join("&", high_school_polygon);
            high_school_polygon_result = downloadService.downloadFromGoogleStaticMap(map_high_school_polygon);
        }


        //所有学校范围图
        System.err.println("school_polygon_result:" + school_polygon_result);
        model.addAttribute("school_polygon_result", school_polygon_result);
        //小学范围图
        System.err.println("elementary_school_polygon_result:" + elementary_school_polygon_result);
        model.addAttribute("elementary_school_polygon_result", elementary_school_polygon_result);
        //初中范围图
        System.err.println("middle_school_polygon_result:" + middle_school_polygon_result);
        model.addAttribute("middle_school_polygon_result", middle_school_polygon_result);
        //高中范围图
        System.err.println("high_school_polygon_result:" + high_school_polygon_result);
        model.addAttribute("high_school_polygon_result", high_school_polygon_result);
    }

    /**
     * 学校出勤范围
     *
     * @param model
     * @param listHub
     */
    public void schoolAttendanceArea(Model model, ListHub listHub) {
        long time = System.currentTimeMillis();

        if (!StringUtils.isEmpty(listHub.getZip())) {

            HouseSchoolDistrictGeometryResult result = new HouseSchoolDistrictGeometryResult();
            result.setAddress(listHub.getAddress());
            result.setLat(listHub.getLatitude());
            result.setLng(listHub.getLongitude());

            System.err.println("house-search-time:" + (System.currentTimeMillis() - time));
            time = System.currentTimeMillis();
            List<SchoolAttendanceAreaResult> schoolDistrictResults = homeJunctionService.selectSchoolAndAttendanceAreaByZip(listHub.getZip());

            System.err.println("school-search-time:" + (System.currentTimeMillis() - time));
            time = System.currentTimeMillis();
            for (SchoolAttendanceAreaResult school : schoolDistrictResults) {
                String attendance_area_id = school.getAttendance_area_id();
                if (!StringUtils.isEmpty(attendance_area_id)) {
                    List<JSONObject> schoolGeometries = getSchoolGeometries(attendance_area_id);
                    if (!schoolGeometries.isEmpty()) {
                        school.setGeometry(schoolGeometries);
                    }
                }
            }
            result.setSchools(schoolDistrictResults);
            System.err.println("school-geometries-time:" + (System.currentTimeMillis() - time));

            model.addAttribute("school_attendance_area", result);
        }
    }


    /**
     * 根据学校ID查询学区范围
     *
     * @param attendance_area_id
     * @return geometry
     */
    public List<JSONObject> getSchoolGeometries(String attendance_area_id) {
        List<JSONObject> geometries = new ArrayList<>();
        String key = "homejunction/attendanceareas/" + attendance_area_id + ".json";

        String json = downloadService.downloadJsonFromOSS(key);

        if (!StringUtils.isEmpty(json)) {
            JSONObject jsonObject = JSONObject.parseObject(json);
            if (jsonObject.get("attendance-areas") != null) {
                JSONArray attendance_areas = JSONObject.parseArray(jsonObject.get("attendance-areas").toString());
                for (int s = 0; s < attendance_areas.size(); s++) {
                    JSONObject attendance_area = attendance_areas.getJSONObject(s);
                    if (attendance_area.get("geometry") != null) {
                        JSONObject geometry = attendance_area.getJSONObject("geometry");
                        geometries.add(geometry);
                    }
                }
            }
        }

        return geometries;
    }

    /**
     * 学校覆盖图  返回json数据
     *
     * @param model
     * @param listHub
     */
    public void school_polygon_coordinates(Model model, ListHub listHub, com.youhome.service.result.School school) {

        HouseSchoolDistrictGeometryResult houseSchoolDistrictGeometryResult = new HouseSchoolDistrictGeometryResult();
        geometries_keys.clear();
        if (listHub != null) {
            houseSchoolDistrictGeometryResult.setAddress(listHub.getAddress());
        }
        if (!StringUtils.isEmpty(listHub.getLatitude()) && !StringUtils.isEmpty(listHub.getLongitude())) {
            houseSchoolDistrictGeometryResult.setLat(listHub.getLatitude());
            houseSchoolDistrictGeometryResult.setLng(listHub.getLongitude());
        }

        List<SchoolItem> elementary = school.getElementary(); //小学
        List<SchoolItem> middle = school.getMiddle(); //初中
        List<SchoolItem> high = school.getHigh(); // 高中

        List<SchoolGeometryResult> schoolGeometryResults = new ArrayList<>(); //所有学校包含房源的范围

        if (elementary != null && elementary.size() > 0) {
            for (SchoolItem item : elementary) {
                SchoolGeometryResult schoolGeometry = getSchoolGeometry(listHub, item);
                if (schoolGeometry != null) {
                    schoolGeometryResults.add(schoolGeometry);
                }
            }
        }

        if (middle != null && middle.size() > 0) {
            for (SchoolItem item : middle) {
                SchoolGeometryResult schoolGeometry = getSchoolGeometry(listHub, item);
                if (schoolGeometry != null) {
                    schoolGeometryResults.add(schoolGeometry);
                }
            }
        }

        if (high != null && high.size() > 0) {
            for (SchoolItem item : high) {
                SchoolGeometryResult schoolGeometry = getSchoolGeometry(listHub, item);
                if (schoolGeometry != null) {
                    schoolGeometryResults.add(schoolGeometry);
                }
            }
        }

        houseSchoolDistrictGeometryResult.setSchools(schoolGeometryResults);

        //所有学校范围图
        System.err.println("house_school_district_geometry_result:" + houseSchoolDistrictGeometryResult);
        model.addAttribute("house_school_district_geometry_result", houseSchoolDistrictGeometryResult);

    }

    /**
     * 判断房源坐标是否在学校区域坐标范围内
     *
     * @param listHub
     * @param school
     * @return
     */
    public SchoolGeometryResult getSchoolGeometry(ListHub listHub, SchoolItem school) {

        List<JSONObject> geometries = analysisSchoolGeometries(listHub, school.getId());
        if (geometries != null && geometries.size() > 0) {
            SchoolGeometryResult geometry = new SchoolGeometryResult();
            geometry.setName(school.getName());
            geometry.setAddress(school.getAddress());
            geometry.setGrade(school.getGrade());
            geometry.setLat(school.getLatitude());
            geometry.setLng(school.getLongitude());
            geometry.setGeometry(geometries);

            return geometry;
        }
        return null;
    }

    /**
     * 学校 点坐标
     *
     * @param model
     * @param listHub
     */
    public void school_point_coordinates(Model model, ListHub listHub, com.youhome.service.result.School school) {
        SchoolShortResult school_coordinates_result = new SchoolShortResult();
        //房源坐标
        HousePoint housePoint = new HousePoint();
        if (!StringUtils.isEmpty(listHub.getLatitude()) && !StringUtils.isEmpty(listHub.getLongitude())) {
            housePoint.setLat(listHub.getLatitude());
            housePoint.setLng(listHub.getLongitude());
            school_coordinates_result.setHouse(housePoint);
        }

        List<SchoolItem> elementarys = school.getElementary(); //小学
        List<SchoolItem> middles = school.getMiddle(); //初中
        List<SchoolItem> highs = school.getHigh(); // 高中

        if (elementarys != null && elementarys.size() > 0) {
            school_coordinates_result.setElementary(extractSchoolCoordinates(elementarys));
        }

        if (middles != null && middles.size() > 0) {
            school_coordinates_result.setMiddle(extractSchoolCoordinates(middles));
        }

        if (highs != null && highs.size() > 0) {
            school_coordinates_result.setHigh(extractSchoolCoordinates(highs));
        }
        //System.err.println("school_coordinates_result:" + school_coordinates_result);
        model.addAttribute("school_coordinates_result", school_coordinates_result);
    }

    /**
     * 学校详情中提取坐标
     *
     * @param list
     * @return
     */
    public List<HousePoint> extractSchoolCoordinates(List<SchoolItem> list) {
        if (list != null && list.size() > 0) {
            List<HousePoint> points = new ArrayList<>();
            for (SchoolItem item : list) {
                HousePoint point = new HousePoint();
                point.setLat(item.getLatitude());
                point.setLng(item.getLongitude());
                points.add(point);
            }
            return points;
        }
        return null;
    }

    /**
     * 根据学校ID查询学区范围
     *
     * @param listHub  房源
     * @param schoolId 学校ID
     * @return geometry
     */
    public List<JSONObject> analysisSchoolGeometries(ListHub listHub, String schoolId) {
        List<JSONObject> geometries = new ArrayList<>();
        if (listHub.getLatitude() == null || listHub.getLongitude() == null) {
            return geometries;
        }
        List<HJSchoolAttendanceArea> hjSchoolAttendanceAreas = hjSchoolAttendanceAreaService.selectBySchoolId(schoolId);
        for (HJSchoolAttendanceArea attendanceArea : hjSchoolAttendanceAreas) {
            ///homejunction/attendanceareas/051bfd294e438bb0bf48f7312288dafa.json
            String key = "homejunction/attendanceareas/" + attendanceArea.getId() + ".json";
            if (!geometries_keys.contains(key)) {
                geometries_keys.add(key);
                System.err.println("key:" + key);
                String json = downloadService.downloadJsonFromOSS(key);
                System.err.println(json);
                if (!StringUtils.isEmpty(json)) {
                    JSONObject jsonObject = JSONObject.parseObject(json);
                    if (jsonObject.get("attendance-areas") != null) {
                        JSONArray attendance_areas = JSONObject.parseArray(jsonObject.get("attendance-areas").toString());
                        for (int s = 0; s < attendance_areas.size(); s++) {

                            JSONObject jsonObject1 = attendance_areas.getJSONObject(s);

                            if (jsonObject1.get("geometry") != null) {
                                JSONObject geometry = (JSONObject) jsonObject1.get("geometry");
                                if (geometry.get("coordinates") != null) {
                                    JSONArray coordinates = JSONObject.parseArray(geometry.get("coordinates").toString());
                                    for (int i = 0; i < coordinates.size(); i++) {
                                        JSONArray jsonArray = coordinates.getJSONArray(i);

                                        for (int j = 0; j < jsonArray.size(); j++) {
                                            JSONArray jsonArray1 = jsonArray.getJSONArray(j);
                                            System.err.println("jsonArray1:" + jsonArray1);
                                            List<Point> points = new ArrayList<>();


                                            for (int k = 0; k < jsonArray1.size(); k++) {
                                                JSONArray jsonArray2 = jsonArray1.getJSONArray(k);
                                                if (jsonArray2 != null) {
                                                    Double lat = Double.valueOf(jsonArray2.get(0).toString());
                                                    Double lng = Double.valueOf(jsonArray2.get(1).toString());
                                                    Point point = new Point(lng, lat);
//                                                    point.x = lng;
//                                                    point.y = lat;
                                                    points.add(point);
                                                }
                                            }
                                            if (points != null && points.size() > 0) {
                                                Point point = new Point(listHub.getLongitude(), listHub.getLatitude());
//                                                point.x = listHub.getLatitude();
//                                                point.y = listHub.getLongitude();
                                                boolean polygonContainsPoint = GoogleMapUtils.isPolygonContainsPoint(points, point);
                                                if (polygonContainsPoint) {
                                                    if (!geometries.contains(geometry)) {
                                                        geometries.add(geometry);
                                                    }
                                                }
                                            }

                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return geometries;
    }

    /**
     * 根据学校信息获取学区图（google static map）
     *
     * @param listHub 房源
     * @param school  学校
     * @return 图片地址
     */
    public List<String> analysisSchoolGeometries(ListHub listHub, SchoolItem school) {
        HJSchool hjSchool = homeJunctionService.selectByPrimaryKey(school.getId());
        String color = setSchoolColor(hjSchool);
        List<String> paths = new ArrayList<>();
        if (listHub.getLatitude() == null || listHub.getLongitude() == null) {
            return paths;
        }
        String marker = "&markers=icon:http://youhome.oss-cn-zhangjiakou.aliyuncs.com/icon/house.png|" + listHub.getLatitude() + "," + listHub.getLongitude();

        List<HJSchoolAttendanceArea> hjSchoolAttendanceAreas = hjSchoolAttendanceAreaService.selectBySchoolId(school.getId());
        for (HJSchoolAttendanceArea attendanceArea : hjSchoolAttendanceAreas) {
            ///homejunction/attendanceareas/051bfd294e438bb0bf48f7312288dafa.json
            String key = "homejunction/attendanceareas/" + attendanceArea.getId() + ".json";
            if (!keys.contains(key)) {
                keys.add(key);
                System.err.println("key:" + key);
                String json = downloadService.downloadJsonFromOSS(key);
                System.err.println(json);
                if (!StringUtils.isEmpty(json)) {
                    JSONObject jsonObject = JSONObject.parseObject(json);
                    if (jsonObject.get("attendance-areas") != null) {
                        JSONArray attendance_areas = JSONObject.parseArray(jsonObject.get("attendance-areas").toString());
                        for (int s = 0; s < attendance_areas.size(); s++) {

                            JSONObject jsonObject1 = attendance_areas.getJSONObject(s);

                            if (jsonObject1.get("geometry") != null) {
                                JSONObject geometry = (JSONObject) jsonObject1.get("geometry");
                                if (geometry.get("coordinates") != null) {
                                    JSONArray coordinates = JSONObject.parseArray(geometry.get("coordinates").toString());
                                    for (int i = 0; i < coordinates.size(); i++) {
                                        JSONArray jsonArray = coordinates.getJSONArray(i);

                                        for (int j = 0; j < jsonArray.size(); j++) {
                                            JSONArray jsonArray1 = jsonArray.getJSONArray(j);
                                            System.err.println("jsonArray1:" + jsonArray1);
                                            List<Point> points = new ArrayList<>();

                                            List<String> coordinate = new ArrayList<>();
                                            //path=fillcolor:bule|color:bule|weight:5|enc:qpg~FxwvuO?xiKppBqcLqpBvX
                                            for (int k = 0; k < jsonArray1.size(); k++) {
                                                JSONArray jsonArray2 = jsonArray1.getJSONArray(k);
                                                if (jsonArray2 != null) {
                                                    Double lat = Double.valueOf(jsonArray2.get(0).toString());
                                                    Double lng = Double.valueOf(jsonArray2.get(1).toString());
                                                    Point point = new Point(lng, lat);
//                                                    point.x = lng;
//                                                    point.y = lat;
                                                    points.add(point);
                                                    //System.err.println(lat + "--" + lng);
                                                    coordinate.add(lng + "," + lat);
                                                }
                                            }
                                            //System.err.println("coordinate:"+coordinate);
                                            if (points != null && points.size() > 0) {
                                                Point point = new Point(listHub.getLongitude(), listHub.getLatitude());
//                                                point.x = listHub.getLatitude();
//                                                point.y = listHub.getLongitude();
                                                boolean polygonContainsPoint = GoogleMapUtils.isPolygonContainsPoint(points, point);
                                                //System.err.println("polygonContainsPoint:" + polygonContainsPoint);
                                                String join = String.join("|", coordinate);
                                                //System.err.println("join:"+join);
                                                String encodings = GPolyline2.createEncodings(join);
                                                String path = "markers=label:S|color:" + color + "|" + hjSchool.getLatitude() + "," + hjSchool.getLongitude() +
                                                        "&path=fillcolor:" + color + "|color:" + color + "|weight:1|enc:" + encodings;
                                                if (polygonContainsPoint) {
                                                    if (!paths.contains(path)) {
                                                        paths.add(path);
                                                        String map = "https://maps.google.cn/maps/api/staticmap?center=&zoom=16&size=640x640&scale=1&maptype=roadmap&key=AIzaSyDH6NBqY397pB_dQfDyb4jLwVD73FeOELU&" + marker + "&" + path;
                                                        System.err.println(map);
                                                    }
                                                }
                                            }

                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        return paths;
    }

    private String setSchoolColor(HJSchool hjSchool) {
        if (hjSchool.getHasElementary()) return "0x008000";
        if (hjSchool.getHasMiddle()) return "0x4169e1";
        if (hjSchool.getHasHigh()) return "0x800000";
        return null;
    }

    /**
     * 根据属性名获取属性值
     */
    private Object getFieldValueByName(String fieldName, Object o) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = o.getClass().getMethod(getter, new Class[]{});
            Object value = method.invoke(o, new Object[]{});
            return value;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 解析人口年龄结构
     *
     * @param json
     * @return
     */
    public PopulationAgeItemResult analysisAge(String json) {

        PopulationAgeItemResult zipPopulationAgeItemResult = new PopulationAgeItemResult();
        if (!StringUtils.isEmpty(json)) {
            JSONObject jsonObject = JSON.parseObject(json);
            if (jsonObject.get("age") != null) {
                JSONObject jsonObject_age = JSON.parseObject(jsonObject.get("age").toString());
                //族裔平均年龄
                RaceItemResult raceResult = new RaceItemResult();
                if (jsonObject_age.get("white") != null) {
                    raceResult.setWhite(Double.valueOf(jsonObject_age.get("white").toString()));
                }
                if (jsonObject_age.get("black") != null) {
                    raceResult.setBlack(Double.valueOf(jsonObject_age.get("black").toString()));
                }
                if (jsonObject_age.get("asian") != null) {
                    raceResult.setAsian(Double.valueOf(jsonObject_age.get("asian").toString()));
                }
                if (jsonObject_age.get("hispanic") != null) {
                    raceResult.setHispanic(Double.valueOf(jsonObject_age.get("hispanic").toString()));
                }
                zipPopulationAgeItemResult.setRace(raceResult);

                //年龄组百分比
                AgeResult ageResult = new AgeResult();
                if (jsonObject_age.get("Y0_5") != null) {
                    ageResult.setY0_5(Double.valueOf(jsonObject_age.get("Y0_5").toString()));
                }
                if (jsonObject_age.get("Y6_11") != null) {
                    ageResult.setY6_11(Double.valueOf(jsonObject_age.get("Y6_11").toString()));
                }
                if (jsonObject_age.get("Y12_17") != null) {
                    ageResult.setY12_17(Double.valueOf(jsonObject_age.get("Y12_17").toString()));
                }
                if (jsonObject_age.get("Y18_24") != null) {
                    ageResult.setY18_24(Double.valueOf(jsonObject_age.get("Y18_24").toString()));
                }
                if (jsonObject_age.get("Y25_34") != null) {
                    ageResult.setY25_34(Double.valueOf(jsonObject_age.get("Y25_34").toString()));
                }
                if (jsonObject_age.get("Y35_44") != null) {
                    ageResult.setY35_44(Double.valueOf(jsonObject_age.get("Y35_44").toString()));
                }
                if (jsonObject_age.get("Y45_54") != null) {
                    ageResult.setY45_54(Double.valueOf(jsonObject_age.get("Y45_54").toString()));
                }
                if (jsonObject_age.get("Y55_64") != null) {
                    ageResult.setY55_64(Double.valueOf(jsonObject_age.get("Y55_64").toString()));
                }
                if (jsonObject_age.get("Y65_74") != null) {
                    ageResult.setY65_74(Double.valueOf(jsonObject_age.get("Y65_74").toString()));
                }
                if (jsonObject_age.get("Y75_84") != null) {
                    ageResult.setY75_84(Double.valueOf(jsonObject_age.get("Y75_84").toString()));
                }
                if (jsonObject_age.get("Y85_UP") != null) {
                    ageResult.setY85_up(Double.valueOf(jsonObject_age.get("Y85_UP").toString()));
                }
                zipPopulationAgeItemResult.setAge(ageResult);

                //性别
                GenderItemResult genderItemResult = new GenderItemResult();
                if (jsonObject_age.get("male") != null) {
                    genderItemResult.setMale(Double.valueOf(jsonObject_age.get("male").toString()));
                }
                if (jsonObject_age.get("female") != null) {
                    genderItemResult.setFemale(Double.valueOf(jsonObject_age.get("female").toString()));
                }
                zipPopulationAgeItemResult.setGender(genderItemResult);
                if (jsonObject_age.get("median") != null) {
                    zipPopulationAgeItemResult.setMedian(Double.valueOf(jsonObject_age.get("median").toString()));
                }
            }
        }
        return zipPopulationAgeItemResult;
    }

    /**
     * 解析生活成本
     *
     * @param json
     * @return
     */
    public CostsItemResult analysisCosts(String json) {
        CostsItemResult costsItemResult = new CostsItemResult();
        if (!StringUtils.isEmpty(json)) {
            JSONObject jsonObject = JSON.parseObject(json);
            if (jsonObject.get("costs") != null) {
                JSONObject costs = JSON.parseObject(jsonObject.get("costs").toString());
                if (costs.get("overall") != null) {
                    costsItemResult.setOverall(Double.valueOf(costs.get("overall").toString()));
                }
                if (costs.get("apparel") != null) {
                    costsItemResult.setApparel(Double.valueOf(costs.get("apparel").toString()));
                }
                if (costs.get("education") != null) {
                    costsItemResult.setEducation(Double.valueOf(costs.get("education").toString()));
                }
                if (costs.get("entertainment") != null) {
                    costsItemResult.setEntertainment(Double.valueOf(costs.get("entertainment").toString()));
                }
                if (costs.get("food") != null) {
                    costsItemResult.setFood(Double.valueOf(costs.get("food").toString()));
                }
                if (costs.get("healthcare") != null) {
                    costsItemResult.setHealthcare(Double.valueOf(costs.get("healthcare").toString()));
                }
                if (costs.get("housing") != null) {
                    costsItemResult.setHousing(Double.valueOf(costs.get("housing").toString()));
                }
                if (costs.get("transportation") != null) {
                    costsItemResult.setTransportation(Double.valueOf(costs.get("transportation").toString()));
                }
                if (costs.get("utilities") != null) {
                    costsItemResult.setUtilities(Double.valueOf(costs.get("utilities").toString()));
                }
            }
        }
        return costsItemResult;
    }

    /**
     * 解析面积
     *
     * @param json
     * @return
     */
    public AreaItemResult analysisArea(String json) {
        AreaItemResult areaItemResult = new AreaItemResult();
        if (!StringUtils.isEmpty(json)) {
            JSONObject jsonObject = JSON.parseObject(json);
            if (jsonObject.get("area") != null) {
                JSONObject area = JSON.parseObject(jsonObject.getString("area"));
                if (area.get("total") != null) {
                    areaItemResult.setTotal(Double.valueOf(area.getString("total")));
                }
                if (area.get("land") != null) {
                    areaItemResult.setLand(Double.valueOf(area.getString("land")));
                }
                if (area.get("water") != null) {
                    areaItemResult.setWater(Double.valueOf(area.getString("water")));
                }
            }
        }
        return areaItemResult;
    }


    /**
     * 解析犯罪数据
     *
     * @param json
     * @return
     */
    public CrimeItemResult analysisCrime(String json) {
        CrimeItemResult crimeItemResult = new CrimeItemResult();
        if (!StringUtils.isEmpty(json)) {
            JSONObject jsonObject = JSON.parseObject(json);
            if (jsonObject.get("crime") != null) {
                JSONObject crime = JSON.parseObject(jsonObject.get("crime").toString());
                if (crime.get("overall") != null) {
                    crimeItemResult.setOverall(Double.valueOf(crime.get("overall").toString()));
                }
                if (crime.get("assault") != null) {
                    crimeItemResult.setAssault(Double.valueOf(crime.get("assault").toString()));
                }
                if (crime.get("burglary") != null) {
                    crimeItemResult.setBurglary(Double.valueOf(crime.get("burglary").toString()));
                }
                if (crime.get("larceny") != null) {
                    crimeItemResult.setLarceny(Double.valueOf(crime.get("larceny").toString()));
                }
                if (crime.get("murder") != null) {
                    crimeItemResult.setMurder(Double.valueOf(crime.get("murder").toString()));
                }
                if (crime.get("rape") != null) {
                    crimeItemResult.setRape(Double.valueOf(crime.get("rape").toString()));
                }
                if (crime.get("robbery") != null) {
                    crimeItemResult.setRobbery(Double.valueOf(crime.get("robbery").toString()));
                }
                if (crime.get("vehicle") != null) {
                    crimeItemResult.setVehicle(Double.valueOf(crime.get("vehicle").toString()));
                }

            }
        }
        return crimeItemResult;
    }

    /**
     * 解析教育数据
     *
     * @param json
     * @return
     */
    public EducationItemResult analysisEducation(String json) {
        EducationItemResult educationItemResult = new EducationItemResult();
        if (!StringUtils.isEmpty(json)) {
            JSONObject jsonObject = JSON.parseObject(json);
            if (jsonObject.get("education") != null) {
                JSONObject education = JSON.parseObject(jsonObject.get("education").toString());
                if (education.get("highschool") != null) {
                    educationItemResult.setHighschool(Double.valueOf(education.get("highschool").toString()));
                }
                if (education.get("associate") != null) {
                    educationItemResult.setAssociate(Double.valueOf(education.get("associate").toString()));
                }
                if (education.get("bachelor") != null) {
                    educationItemResult.setBachelor(Double.valueOf(education.get("bachelor").toString()));
                }
                if (education.get("graduate") != null) {
                    educationItemResult.setGraduate(Double.valueOf(education.get("graduate").toString()));
                }
            }
        }
        return educationItemResult;
    }

    /**
     * 解析就业数据
     *
     * @param json
     * @return
     */
    public EmploymentItemResult analysisEmployment(String json) {
        EmploymentItemResult employmentItemResult = new EmploymentItemResult();
        if (!StringUtils.isEmpty(json)) {
            JSONObject jsonObject = JSON.parseObject(json);
            if (jsonObject.get("employment") != null) {
                JSONObject employment = JSON.parseObject(jsonObject.get("employment").toString());

                if (employment.get("accommodations") != null) {
                    employmentItemResult.setAccommodations(Double.valueOf(employment.get("accommodations").toString()));
                }
                if (employment.get("administration") != null) {
                    employmentItemResult.setAdministration(Double.valueOf(employment.get("administration").toString()));
                }
                if (employment.get("agriculture") != null) {
                    employmentItemResult.setAgriculture(Double.valueOf(employment.get("agriculture").toString()));
                }
                if (employment.get("arts") != null) {
                    employmentItemResult.setArts(Double.valueOf(employment.get("arts").toString()));
                }
                if (employment.get("construction") != null) {
                    employmentItemResult.setConstruction(Double.valueOf(employment.get("construction").toString()));
                }
                if (employment.get("education") != null) {
                    employmentItemResult.setEducation(Double.valueOf(employment.get("education").toString()));
                }
                if (employment.get("finance") != null) {
                    employmentItemResult.setFinance(Double.valueOf(employment.get("finance").toString()));
                }
                if (employment.get("government") != null) {
                    employmentItemResult.setGovernment(Double.valueOf(employment.get("government").toString()));
                }
                if (employment.get("healthcare") != null) {
                    employmentItemResult.setHealthcare(Double.valueOf(employment.get("healthcare").toString()));
                }
                if (employment.get("management") != null) {
                    employmentItemResult.setManagement(Double.valueOf(employment.get("management").toString()));
                }
                if (employment.get("manufacturing") != null) {
                    employmentItemResult.setManufacturing(Double.valueOf(employment.get("manufacturing").toString()));
                }
                if (employment.get("mining") != null) {
                    employmentItemResult.setMining(Double.valueOf(employment.get("mining").toString()));
                }
                if (employment.get("other") != null) {
                    employmentItemResult.setOther(Double.valueOf(employment.get("other").toString()));
                }
                if (employment.get("professional") != null) {
                    employmentItemResult.setProfessional(Double.valueOf(employment.get("professional").toString()));
                }
                if (employment.get("realestate") != null) {
                    employmentItemResult.setRealestate(Double.valueOf(employment.get("realestate").toString()));
                }
                if (employment.get("retail") != null) {
                    employmentItemResult.setRetail(Double.valueOf(employment.get("retail").toString()));
                }
                if (employment.get("technology") != null) {
                    employmentItemResult.setTechnology(Double.valueOf(employment.get("technology").toString()));
                }
                if (employment.get("transportation") != null) {
                    employmentItemResult.setTransportation(Double.valueOf(employment.get("transportation").toString()));
                }
                if (employment.get("utilities") != null) {
                    employmentItemResult.setUtilities(Double.valueOf(employment.get("utilities").toString()));
                }
                if (employment.get("wholesale") != null) {
                    employmentItemResult.setWholesale(Double.valueOf(employment.get("wholesale").toString()));
                }
            }
        }
        return employmentItemResult;
    }

    /**
     * 解析性别
     *
     * @param json
     * @return
     */
    public GenderItemResult analysisGender(String json) {
        GenderItemResult genderItemResult = new GenderItemResult();
        if (!StringUtils.isEmpty(json)) {
            JSONObject jsonObject = JSON.parseObject(json);
            if (jsonObject.get("gender") != null) {
                JSONObject gender = JSON.parseObject(jsonObject.get("gender").toString());

                if (gender.get("male") != null) {
                    genderItemResult.setMale(Double.valueOf(gender.get("male").toString()));
                }
                if (gender.get("female") != null) {
                    genderItemResult.setFemale(Double.valueOf(gender.get("female").toString()));
                }
            }
        }
        return genderItemResult;
    }

    /**
     * 解析同屋居住者
     *
     * @param json
     * @return
     */
    public HouseholdItemResult analysisHousehold(String json) {
        HouseholdItemResult householdItemResult = new HouseholdItemResult();
        if (!StringUtils.isEmpty(json)) {
            JSONObject jsonObject = JSON.parseObject(json);
            if (jsonObject.get("households") != null) {
                JSONObject households = JSON.parseObject(jsonObject.get("households").toString());

                if (households.get("total") != null) {
                    householdItemResult.setTotal(Double.valueOf(households.get("total").toString()));
                }
                if (households.get("value") != null) {
                    householdItemResult.setValue(Double.valueOf(households.get("value").toString()));
                }
                if (households.get("yearBuilt") != null) {
                    householdItemResult.setYear_built(Double.valueOf(households.get("yearBuilt").toString()));
                }
                if (households.get("duration") != null) {
                    householdItemResult.setDuration(Double.valueOf(households.get("duration").toString()));
                }
                if (households.get("occupancy") != null) {
                    JSONObject occupancy = JSON.parseObject(households.get("occupancy").toString());
                    OccupancyResult occupancyResult = new OccupancyResult();
                    if (occupancy.get("owned") != null) {
                        occupancyResult.setOwned(Double.valueOf(occupancy.get("owned").toString()));
                    }
                    if (occupancy.get("rented") != null) {
                        occupancyResult.setRented(Double.valueOf(occupancy.get("rented").toString()));
                    }
                    if (occupancy.get("vacant") != null) {
                        occupancyResult.setVacant(Double.valueOf(occupancy.get("vacant").toString()));
                    }
                    if (occupancy.get("families") != null) {
                        occupancyResult.setFamilies(Double.valueOf(occupancy.get("families").toString()));
                    }
                    if (occupancy.get("married") != null) {
                        occupancyResult.setMarried(Double.valueOf(occupancy.get("married").toString()));
                    }
                    if (occupancy.get("children") != null) {
                        occupancyResult.setChildren(Double.valueOf(occupancy.get("children").toString()));
                    }
                    householdItemResult.setOccupancy(occupancyResult);
                }
            }
        }
        return householdItemResult;
    }

    /**
     * 解析收入
     *
     * @param json
     * @return
     */
    public IncomeItemResult analysisIncome(String json) {
        IncomeItemResult incomeItemResult = new IncomeItemResult();
        if (!StringUtils.isEmpty(json)) {
            JSONObject jsonObject = JSON.parseObject(json);
            if (jsonObject.get("income") != null) {
                JSONObject income = JSON.parseObject(jsonObject.get("income").toString());

                if (income.get("average") != null) {
                    incomeItemResult.setAverage(Double.valueOf(income.get("average").toString()));
                }
                if (income.get("median") != null) {
                    incomeItemResult.setMedian(Double.valueOf(income.get("median").toString()));
                }
                if (income.get("percent0_15") != null) {
                    incomeItemResult.setPercent0_15(Double.valueOf(income.get("percent0_15").toString()));
                }
                if (income.get("percent15_25") != null) {
                    incomeItemResult.setPercent15_25(Double.valueOf(income.get("percent15_25").toString()));
                }
                if (income.get("percent25_35") != null) {
                    incomeItemResult.setPercent25_35(Double.valueOf(income.get("percent25_35").toString()));
                }
                if (income.get("percent35_50") != null) {
                    incomeItemResult.setPercent35_50(Double.valueOf(income.get("percent35_50").toString()));
                }
                if (income.get("percent50_75") != null) {
                    incomeItemResult.setPercent50_75(Double.valueOf(income.get("percent50_75").toString()));
                }
                if (income.get("percent75_100") != null) {
                    incomeItemResult.setPercent75_100(Double.valueOf(income.get("percent75_100").toString()));
                }
                if (income.get("percent100_125") != null) {
                    incomeItemResult.setPercent100_125(Double.valueOf(income.get("percent100_125").toString()));
                }
                if (income.get("percent125_150") != null) {
                    incomeItemResult.setPercent125_150(Double.valueOf(income.get("percent125_150").toString()));
                }
                if (income.get("percent150_200") != null) {
                    incomeItemResult.setPercent150_200(Double.valueOf(income.get("percent150_200").toString()));
                }
                if (income.get("percent200_up") != null) {
                    incomeItemResult.setPercent200_up(Double.valueOf(income.get("percent200_up").toString()));
                }

            }
        }
        return incomeItemResult;
    }

    /**
     * 解析人口
     *
     * @param json
     * @return
     */
    public PopulationItemResult analysisPopulation(String json) {
        PopulationItemResult populationItemResult = new PopulationItemResult();
        if (!StringUtils.isEmpty(json)) {
            JSONObject jsonObject = JSON.parseObject(json);
            if (jsonObject.get("population") != null) {
                JSONObject population = JSON.parseObject(jsonObject.get("population").toString());

                if (population.get("current") != null) {
                    populationItemResult.setCurrent(Double.valueOf(population.get("current").toString()));
                }
                if (population.get("density") != null) {
                    populationItemResult.setDensity(Double.valueOf(population.get("density").toString()));
                }
                if (population.get("1990") != null) {
                    populationItemResult.setY1990(Double.valueOf(population.get("1990").toString()));
                }
                if (population.get("2000") != null) {
                    populationItemResult.setY2000(Double.valueOf(population.get("2000").toString()));
                }
                if (population.get("2010") != null) {
                    populationItemResult.setY2010(Double.valueOf(population.get("2010").toString()));
                }
            }
        }
        return populationItemResult;
    }

    /**
     * 解析族裔
     *
     * @param json
     * @return
     */
    public RaceItemResult analysisRace(String json) {
        RaceItemResult raceItemResult = new RaceItemResult();
        if (!StringUtils.isEmpty(json)) {
            JSONObject jsonObject = JSON.parseObject(json);
            if (jsonObject.get("race") != null) {
                JSONObject race = JSON.parseObject(jsonObject.get("race").toString());

                if (race.get("white") != null) {
                    raceItemResult.setWhite(Double.valueOf(race.get("white").toString()));
                }
                if (race.get("black") != null) {
                    raceItemResult.setBlack(Double.valueOf(race.get("black").toString()));
                }
                if (race.get("asian") != null) {
                    raceItemResult.setAsian(Double.valueOf(race.get("asian").toString()));
                }
                if (race.get("hispanic") != null) {
                    raceItemResult.setHispanic(Double.valueOf(race.get("hispanic").toString()));
                }
                if (race.get("native") != null) {
                    raceItemResult.setNatives(Double.valueOf(race.get("native").toString()));
                }
            }
        }
        return raceItemResult;
    }

    /**
     * 解析气候数据
     *
     * @param json
     * @return
     */
    public WeatherItemResult analysisWeather(String json) {
        WeatherItemResult weatherItemResult = new WeatherItemResult();
        if (!StringUtils.isEmpty(json)) {
            JSONObject jsonObject = JSON.parseObject(json);
            if (jsonObject.get("weather") != null) {
                JSONObject weather = JSON.parseObject(jsonObject.get("weather").toString());

                if (weather.get("jan") != null) {
                    JSONObject jan = JSON.parseObject(weather.get("jan").toString());
                    Temperature temperature = new Temperature();
                    if (jan.get("low") != null) {
                        temperature.setLow(Double.valueOf(jan.get("low").toString()));
                    }
                    if (jan.get("high") != null) {
                        temperature.setHigh(Double.valueOf(jan.get("high").toString()));
                    }
                    weatherItemResult.setJan(temperature);
                }

                if (weather.get("apr") != null) {
                    JSONObject apr = JSON.parseObject(weather.get("apr").toString());
                    Temperature temperature = new Temperature();
                    if (apr.get("low") != null) {
                        temperature.setLow(Double.valueOf(apr.get("low").toString()));
                    }
                    if (apr.get("high") != null) {
                        temperature.setHigh(Double.valueOf(apr.get("high").toString()));
                    }
                    weatherItemResult.setApr(temperature);
                }

                if (weather.get("jul") != null) {
                    JSONObject jul = JSON.parseObject(weather.get("jul").toString());
                    Temperature temperature = new Temperature();
                    if (jul.get("low") != null) {
                        temperature.setLow(Double.valueOf(jul.get("low").toString()));
                    }
                    if (jul.get("high") != null) {
                        temperature.setHigh(Double.valueOf(jul.get("high").toString()));
                    }
                    weatherItemResult.setJul(temperature);
                }

                if (weather.get("oct") != null) {
                    JSONObject oct = JSON.parseObject(weather.get("oct").toString());
                    Temperature temperature = new Temperature();
                    if (oct.get("low") != null) {
                        temperature.setLow(Double.valueOf(oct.get("low").toString()));
                    }
                    if (oct.get("high") != null) {
                        temperature.setHigh(Double.valueOf(oct.get("high").toString()));
                    }
                    weatherItemResult.setOct(temperature);
                }

                if (weather.get("annual") != null) {
                    JSONObject annual = JSON.parseObject(weather.get("annual").toString());
                    Temperature temperature = new Temperature();
                    if (annual.get("low") != null) {
                        temperature.setLow(Double.valueOf(annual.get("low").toString()));
                    }
                    if (annual.get("high") != null) {
                        temperature.setHigh(Double.valueOf(annual.get("high").toString()));
                    }
                    weatherItemResult.setAnnual(temperature);
                }

                if (weather.get("precipitation") != null) {
                    JSONObject precipitationJson = JSON.parseObject(weather.get("precipitation").toString());
                    Precipitation precipitation = new Precipitation();
                    if (precipitationJson.get("snow") != null) {
                        JSONObject snowJson = JSON.parseObject(precipitationJson.get("snow").toString());
                        Snow snow = new Snow();
                        if (snowJson.get("amount") != null) {
                            snow.setAmount(Double.valueOf(snowJson.get("amount").toString()));
                        }
                        if (snowJson.get("daysPerYear") != null) {
                            snow.setDays_per_year(Integer.valueOf(snowJson.get("daysPerYear").toString()));
                        }
                        precipitation.setSnow(snow);
                    }
                    if (precipitationJson.get("rain") != null) {
                        JSONObject rainJson = JSON.parseObject(precipitationJson.get("rain").toString());
                        Rain rain = new Rain();
                        if (rainJson.get("amount") != null) {
                            rain.setAmount(Double.valueOf(rainJson.get("amount").toString()));
                        }
                        if (rainJson.get("daysPerYear") != null) {
                            rain.setDays_per_year(Integer.valueOf(rainJson.get("daysPerYear").toString()));
                        }
                        precipitation.setRain(rain);
                    }
                    weatherItemResult.setPrecipitation(precipitation);
                }

                if (weather.get("indices") != null) {
                    JSONObject indicesJson = JSON.parseObject(weather.get("indices").toString());
                    Indices indices = new Indices();
                    if (indicesJson.get("earthquake") != null) {
                        indices.setEarthquake(Integer.valueOf(indicesJson.get("earthquake").toString()));
                    }
                    if (indicesJson.get("hail") != null) {
                        indices.setHail(Integer.valueOf(indicesJson.get("hail").toString()));
                    }
                    if (indicesJson.get("hurricane") != null) {
                        indices.setHurricane(Integer.valueOf(indicesJson.get("hurricane").toString()));
                    }
                    if (indicesJson.get("overall") != null) {
                        indices.setOverall(Integer.valueOf(indicesJson.get("overall").toString()));
                    }
                    if (indicesJson.get("ozone") != null) {
                        indices.setOzone(Integer.valueOf(indicesJson.get("ozone").toString()));
                    }
                    if (indicesJson.get("pollution") != null) {
                        indices.setPollution(Integer.valueOf(indicesJson.get("pollution").toString()));
                    }
                    if (indicesJson.get("tornado") != null) {
                        indices.setTornado(Integer.valueOf(indicesJson.get("tornado").toString()));
                    }
                    if (indicesJson.get("wind") != null) {
                        indices.setWind(Integer.valueOf(indicesJson.get("wind").toString()));
                    }
                    weatherItemResult.setIndices(indices);
                }
            }
        }
        return weatherItemResult;
    }

}
